Hello, OnlineGDB Q&A section lets you put your programming query to fellow community users. Asking a solution for whole assignment is strictly not allowed. You may ask for help where you are stuck. Try to add as much information as possible so that fellow users can know about your problem statement easily.

Unable to get percentage with 'int' even though value is within range. Works with 'long' though. Why?

+6 votes
asked Dec 14, 2023 by ToasterPizza (220 points)
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

1 Answer

+1 vote
answered Dec 14, 2023 by Peter Minarik (86,240 points)
selected Dec 15, 2023 by ToasterPizza
 
Best answer

Types Matter

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

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

But why are the results different?

Signed int, a.k.a. int32

A signed int can take any 32-bit integral value in the range [-231, 231-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.

Signed long int, a.k.a. int64

signed long int can take any 64-bit integral value in the range [-261, 261-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
commented Dec 15, 2023 by Peter Minarik (86,240 points)
I'm happy to have been able to help. :)
Welcome to OnlineGDB Q&A, where you can ask questions related to programming and OnlineGDB IDE and and receive answers from other members of the community.
...