+6 votes

Below is a simplified snippet of a problem I am trying to solve. Can anyone explain to me why is util2=49, but util1=5?

Program:

#include <stdio.h>

int main()

{

int flyte_load1 = 47759534;

int flyte_capactiy1 = 96000000;

long flyte_load2 = 47759534;

int flyte_capactiy2 = 96000000;

int util1 = (100*flyte_load1)/flyte_capactiy1;

int util2 = (100*flyte_load2)/flyte_capactiy2;

printf("util1 = %d\n", util1);

printf("util2 = %d\n", util2);

return 0;

}

Output:

util1 = 5

util2 = 49

Program:

#include <stdio.h>

int main()

{

int flyte_load1 = 47759534;

int flyte_capactiy1 = 96000000;

long flyte_load2 = 47759534;

int flyte_capactiy2 = 96000000;

int util1 = (100*flyte_load1)/flyte_capactiy1;

int util2 = (100*flyte_load2)/flyte_capactiy2;

printf("util1 = %d\n", util1);

printf("util2 = %d\n", util2);

return 0;

}

Output:

util1 = 5

util2 = 49

+1 vote

Best answer

In the first example, we calculate 100 * 47759534 / 96000000.

In the second example, we calculate 100 * 47759534 / 96000000.

But why are the results different?

A signed int can take any 32-bit integral value in the range [-2^{31}, 2^{31}-1], i.e. from -2,147,483,648 to 2,147,483,647.

In the first example, flyte_load1 and flyte_capactiy1 are both of type int (i.e. signed int) and so is the numeric literal 100.

So the calculation 100 * 47759534 / 96000000 regarding the types look like: int * int / int. Operations performed on int types result in int types.

So int 100 * int 47759534 = int 4775953400. However, we've run into a problem here. 4,775,953,400 is larger than the maximum number that the int type can store, i.e. 2,147,483,647. When this happens an *overflow* occurs and after the largest possible number, the smallest possible number is the next increment in value. So if we take overflow into account our result is 480,986,105 (because there's 4,775,953,400 - 2,147,483,647 = 2,628,469,753 left above the maximum and you have to start over from the minimum of -2,147,483,648, so -2,147,483,648 + 2,628,469,753 = 480,986,105).

Now, what's left is the integral division of 480,986,105 by 96,000,000. The point of the integral division is that you are interested only in the integral parts, but not in the fractions. So the result of 480,986,105 / 96,000,000 would be 5.010271927083, but we'll hold onto the integral part, so the result is 5.

**And that's why util1 is 5.**

A signed long int can take any 64-bit integral value in the range [-2^{61}, 2^{61}-1], i.e. from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807.

In the second example, flyte_load2 is a long int, and flyte_capactiy2 and the numeric literal 100 are both of type int (i.e. signed int).

So the calculation 100 * 47759534 / 96000000 regarding the types look like: int * long int / int. Operations performed on int types result in int types but operations performed on long int types result in long int types. For simplicity, you can consider the larger type will be the result of two types of different sizes are used (in our example 32-bit and 64-bit int types)

So int 100 * long int 47759534 = long int 4775953400. This time no overflow happens, as 4,775,953,400 is less than the maximum 9,223,372,036,854,775,807.

Now, what's left is the integral division of long int 96,000,000 / int 96,000,000. Again, the result will be a long int. So we'll absolutely have enough space to store the number (even int would do fine, as a matter of fact, even one byte could store the result). Again, we're interested in the integral part of the division, which is 49.749514583, and the integral part is 49.

**And that's why util2 is 49.**

I hope this helped understand what's happening.

commented
Dec 15, 2023
by
ToasterPizza
(220 points)

Thanks so much! There couldn't have been a better explanation

...