long long int n = 2000*2000*2000*2000; // overflow
long long int n = pow(2000,4); // works
long long int n = 16000000000000; // works
Why does the first one overflow (multiplying integer literal constants to assign to a long long)?
What's different about it vs. the second or third ones?
Because 2000
is an int
which is usually 32-bit. Just use 2000LL
.
Using LL
suffix instead of ll
was suggested by @AdrianMole in, now deleted, comment. Please check his answer.
By default, integer literals are of the smallest type that can hold their value but not smaller than int
. 2000
can easily be stored in an int since the Standard guarantees it is effectively at least a 16-bit type.
Arithmetic operators are always called with the larger of the types present but not smaller than int
:
char*char
will be promoted to operator*(int,int)->int
char*int
calls operator*(int,int)->int
long*int
calls operator*(long,long)->long
int*int
still calls operator*(int,int)->int
.The type is not dependent on whether the result can be stored in the inferred type. Which is exactly the problem happening in your case - multiplication is done with int
s but the result overflows as it is still stored as int
.
C++ does not support inferring types based on their destination like Haskell can so the assignment is irrelevant.