3 * 1000000000 overflows as an int, but the variable is long long. Why?
Integer constants are, by default int
s.
1000000000
That can fit into an int
. So, this constant gets parsed as an int
. But multiplying it by 3 overflows int.
10000000000
This is too big to an int, so this constant is a long long
, so the resulting multiplication does not overflow.
Solution: explicitly use long long
constants:
long long calcOne = 3 * 100000000LL; // 3e8, essentially
long long calcTwo = 3 * 1000000000LL; // 3e9, essentially
long long calcThree = 3 * 10000000000LL; // 3e10, essentially
What you do with a result doesn't affect how that result is calculated. So the fact that you store the result in a long long
doesn't change the fact that the numbers you multiplied in the second line of code were not long long
s and so they overflowed. In the third line of code, the constant is a long long
, so the multiplication is performed on long long
s.
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 calcTwo
right hand value was inferred as an int
type and then over flowed. You see the over flow as a negative long.
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 explicit as to the types of your static values.To tell the compiler a number is a long long
post fix it with LL.