3 * 1000000000 overflows as an int, but the variable is long. What for?

I have a simple C ++ application that does the following calculations

long long calcOne = 3 * 100000000;     // 3e8, essentially
long long calcTwo = 3 * 1000000000;    // 3e9, essentially
long long calcThree = 3 * 10000000000; // 3e10, essentially

      

If I write the result of each calculation, I get the following output:

calcOne = 300000000
calcTwo = -1294967296
calcThree = 30000000000

      

So why isn't the second calculation done? As far as I can tell, it falls within the long long type (calcThree was bigger ...).

I am using Visual Studio 2015 on Windows 10. Thanks in advance.

+3


source to share


4 answers


Default integer constants int

s.

1000000000

      

It can fit in int

. So this constant is parsed as int

. But multiplying it by 3 int overflows.

10000000000

      



This is too large a value for an int, so this constant is long long

, so the resulting multiplication does not overflow.

Solution: use constants explicitly long long

:

long long calcOne = 3 * 100000000LL;     // 3e8, essentially
long long calcTwo = 3 * 1000000000LL;    // 3e9, essentially
long long calcThree = 3 * 10000000000LL; // 3e10, essentially

      

+7


source


What you do with a result does not affect how that result is calculated. Thus, the fact that the result is stored in long long

does not change the fact that the numbers you multiplied in the second line of code were not long long

and therefore overflowed. In the third line of code, the constant is long long

, so the multiplication is performed by long long

s.



+2


source


The compiler saw this

long long calcOne = (int) 3 * (int) 100000000;     // 3e8, essentially
long long calcTwo = (int) 3 * (int) 1000000000;    // 3e9, essentially
long long calcThree = (int) 3 * (long long) 10000000000; // 3e10, essentially

      

And so the right value calcTwo

was inferred as a type int

and then spilled over. You can see that the flow is too negative.

long long calcOne = 3LL * 100000000LL;     // 3e8, essentially
long long calcTwo = 3LL * 1000000000LL;    // 3e9, essentially
long long calcThree = 3LL * 10000000000LL; // 3e10, essentially

      

To avoid this in the future, be clear about the types of your static values. To tell the compiler that the number is a message long long

, correct it with LL.

+1


source


Most programming languages ​​rank numbers by size. Numeric Expression Type / Rank / Type (usually) - The type of the highest ranked value in the expression.

Example: int * double β†’ double

Your program has: long long int = int * int.

What happens is that the result of an int * int is an int. So your program will multiply first and process the result as an integer value (max value ~ = 2 billion, so it wraps around negative numbers). This negative value is then stored in a long int.

300 million (your first multiplication) fits into an int. No problems. I assume the third one works correctly because the compiler is smart enough to know that 30 billion doesn't fit into a 32 bit int and automatically gives it a 64 bit long int.

0


source







All Articles