Reputation: 1049
When I run the following code under Windows7 x64, compiled with GCC of MinGW, the result seems to be underflowed:
cout<<-2147483648 ; //Output: 2147483648
but when I assigned it to a integer variable, or just simply convert it to the int type :
cout<<(int)-2147483648 ; //Output: -2147483648
So, what's wrong with the previous version of my code? Istn't it the type int? or what the lower bound the Integer is exactly? Many thanks.
Upvotes: 10
Views: 7332
Reputation: 1049
Actually I found an explaination from a pdf file of CS:APP which perfectly give the solution, you can download it from here. http://www.csapp.cs.cmu.edu/public/waside/waside-tmin.pdf
Upvotes: 0
Reputation: 214930
First of all, it is important to understand that there are no negative integer literals.
Others have explained why the OP's particular compiler behaves as it does. But for the record, this is what the compiler should do, between the lines, on a 32-bit system:
int
of two's complement format.int
, if it doesn't fit, try a long
, if it doesn't fit there either, try a long long
, if it doesn't fit there either, we have undefined behavior. A C or C++ compiler following the latest standard will not attempt to fit it in unsigned types.int
nor in a long
, so the compiler decides to use a long long
as type for the literal.long long
as the type.(1) This "internal table" looks different if you have an unsigned suffix, or if you have hex format etc. If there is an unsigned suffix, it will only check if the number fits in unsigned numbers. If there is hex notation (but no suffix), it will check int, then unsigned int, then long and so on.
Upvotes: 2
Reputation: 254721
So, what's wrong with the previous version of my code?
Presumably, you're using a pre-2011 compiler, and on your system long
has 32 bits. The value (-231) isn't guaranteed to fit into long
, so it might overflow. That gives undefined behaviour, so you could see anything.
The most likely explanation for the particular value you see (231) is that, in the absence of defined behaviour in C++, your compiler is using the old C90 rules, and converting the value to unsigned long
.
Istn't it the type int?
Before 2011, it was int
if the value is representable by int
, otherwise long
, with undefined behaviour if that isn't sufficient. C++11 adds the long long
type, and allows that to be used for integer literals if long
isn't big enough.
or what the lower bound the Integer is exactly?
Signed integer types with N bits have a range of at least -2(N-1)+1 to 2(N-1)-1. Your value is -231, which is just out of range for a 32-bit signed type.
The language doesn't specify the exact size of the integer types; just that int
must have at least 16 bits, long
at least 32, and (since 2011) long long
at least 64.
Upvotes: 3
Reputation:
2147483648 doesn't fit into an int or a long on your system, so it's treated as a constant of type unsigned long. (Edit: as ouah pointed out in the comments, it's undefined behaviour in standard C++, but your compiler accepts it as an extension.) Negating an unsigned integer value is possible, but results in another unsigned integer value, never a negative number. Negating 2147483648UL produces 2147483648UL (assuming, as is the case on your system, that unsigned long is a 32 bit type).
Casting that to int
produces an implementation-defined result, commonly the result you see, but not necessarily. You can get the result you want without any conversions by writing -2147483647 - 1.
Upvotes: 11