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.
source to share
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
source to share
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.
source to share
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.
source to share
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.
source to share