Hi, I am currently learning how to program, and have a code below:

int voltage;
    printf("Voltage\t\tSoC\tDescription\n");
    printf("-------\t\t---\t-----------\n");
    for (voltage = voltage_min; voltage <= voltage_max; voltage = voltage + step_size_variable){
        printf("%d\t\t%0.3d%%\n", voltage, ((voltage - 3000)/1200)*100);
    } 

When I run it, the program outputs only 0.00%s, and is not calculating the voltage according to the equation that is inside in the last printf(). Is there any advice to this work...?

Dani AI

Generated

nailed the root cause: all-int math truncates toward zero, so your percentage stays 0 until the numerator reaches the divisor. Also note %0.3d prints a zero-padded integer, not a fixed decimal. If you want one decimal place, compute the value in floating point and print with %.1f. As suggested, separating calculation from printing makes the bug obvious and the code easier to test.

A small helper keeps the intent clear and fixes the truncation by promoting at least one operand to floating point:

static double soc_from_mv(int mv) {
    const int V_MIN_MV = 3000;
    const int V_MAX_MV = 4200;
    const int V_RANGE_MV = V_MAX_MV - V_MIN_MV;

    double pct = 100.0 * ((double)mv - (double)V_MIN_MV) / (double)V_RANGE_MV;
    if (pct < 0.0) pct = 0.0;
    if (pct > 100.0) pct = 100.0;
    return pct;
}

// usage inside your loop:
double soc = soc_from_mv(voltage);
printf("%dmV\t\t%5.1f%%\n", voltage, soc);

A few more practical tips:

  • Do the math inside the loop body rather than in the for header; it avoids repeating the formula and mistakes when you change the step. That aligns with ’s and ’s advice to adjust the order of operations, but keeps it readable.
  • If you want whole-percent output without bias, round instead of truncating: int soc_int = (int)lround(soc); and print with %d%%. Include <math.h>.
  • Make the ranges mutually exclusive with else if to prevent multiple messages for one row, and validate inputs (step > 0, min <= max).
  • Avoid magic numbers: keep 3000/4200 in named constants so it is obvious what the math represents.

Recommended Answers

All 9 Replies

You don't indicate what voltage_min and voltage_max may be.

See, if it confuses you so much then maybe separate calculation and printing, and print result variable only.
Also can write function to calculate

For values of voltage less than 4200, you'll always get zero. This is because of the way integer arithmetic works.

I dislike working with floating point numbers too, but this looks like a case where they would make sense.

Alternately, you could get slightly better results by moving the 100 multiplier in front so your intermediate value doesn't dip to zero.

(100 * (voltage - 3000) / 1200)

You should try to multiply it first thn divide,

((voltage-3000)*100)/1200

Why not then

 (voltage - 3000) / 12.0

Thank you guys for your advices. I haved moved the equation out of the printf(), and declared a floating point variable like below. The program is doing the math, but is truncating the results, even when I force it to disply 1 decimal point. How can I fix it? I also posted the entire code below for reference.

for (voltage = voltage_min, battery_remain = ((voltage - 3000) * 100) /1200; voltage <= voltage_max; voltage = voltage + step_size_variable, battery_remain = ( (voltage + step_size_variable - 3000) * 100) / 1200)






#include <stdio.h>
#include <math.h>

int main()
{

    printf("Welcome to the Battery State Of Charge (SoC) Table Generator\n");
    printf("------------------------------------------------------------\n");

    //ask the user for battery information
    int voltage_min = 0;
    int voltage_max = 0;
    int step_size_variable = 0;
    printf("Enter min & max voltages (mV) to show in the table: ");
    scanf("%d%d", &voltage_min, &voltage_max);
    printf("Enter the step size between voltages: ");
    scanf("%d", &step_size_variable);

    //determine the variables and constants needed to calculate voltage
    int voltage; 
    float battery_remain;
    const int voltage_min_allowance = 3000;
    const int voltage_max_allowance = 4200;
    const int OVERCHARGE_VOLTAGE = 4250;
    printf("Voltage\t\t   SoC\tDescription\n");
    printf("-------\t\t------\t-----------\n");

    //calculate the voltage
    for (voltage = voltage_min, battery_remain = ((voltage - 3000) * 100) /1200; voltage <= voltage_max; voltage = voltage + step_size_variable, battery_remain = ( (voltage + step_size_variable - 3000) * 100) / 1200)
    {
        if(voltage < voltage_min_allowance){
            battery_remain = 0; 
        }
        if(voltage >= voltage_max_allowance){
            battery_remain = 100;
        }
        if(battery_remain >= 0 && battery_remain < 10){
            printf("%dmV\t\t%6.1f%%\tRecharge Soon!\n", voltage, battery_remain);
        }
        if(battery_remain >= 10 && battery_remain < 25){
            printf("%dmV\t\t%6.1f%%\tLow!\n", voltage, battery_remain);
        }
        if(battery_remain >= 25 && battery_remain < 90){
            printf("%dmV\t\t%6.1f%%\tGood!\n", voltage, battery_remain);
        } 
        if(battery_remain >= 90 && battery_remain < 100){
            printf("%dmV\t\t%6.1f%%\tFull!\n", voltage, battery_remain);
        }
        if(battery_remain >= 100 && voltage < OVERCHARGE_VOLTAGE){
            printf("%dmV\t\t%6.1f%%\tFull!\n", voltage, battery_remain);
        }
        if(voltage >= OVERCHARGE_VOLTAGE){
            printf("%dmV\t\t%6.1f%%\tWARNING: OVERCHARGED!\n", voltage, battery_remain);
        }
    } 

    return 0;
}

You have still the same old integer formula

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.