I have the following source compiled in Linux 3.10.0-957.5.1.el7.x86_64,g++ version 4.8.5
Case1:
printf("INT_MAX=(%d) , INT_MIN=(%d) \n",INT_MAX,INT_MIN);
int ix= 500 ;
long int lx1=0,lx2=0;
lx1=2147483647 + 10 ;
lx2=2100000000 ;
if( ix < (lx1-lx2) )
printf("ix is not bigger \n");
else
printf("ix is bigger \n");
compiled with warning :
warning: integer overflow in expression [-Woverflow]
lx1=2147483647 + 10 ;
and output :
INT_MAX=(2147483647) , INT_MIN=(-2147483648)
ix is bigger
and the following source Case2 :
printf("INT_MAX=(%d) , INT_MIN=(%d) \n",INT_MAX,INT_MIN);
int ix= 500 ;
long int lx1=0,lx2=0;
lx1=2200000000 + 10 ;
lx2=2100000000 ;
if( ix < (lx1-lx2) )
printf("ix is not bigger \n");
else
printf("ix is bigger \n");
compiled without warning and the output :
INT_MAX=(2147483647) , INT_MIN=(-2147483648)
ix is not bigger
My question : Why Case1 output can be wrong ? lx1 and lx2 both long int, in this box it is size 8 bytes , how come 2200000000 is fine but 2147483647 is not for lx1 ?!
Comparing int with long and others is referd , still can not figure it out .
The calculation of 2147483647 + 10
happens with int
datatypes, because both values fit into an int
. The result overflows and then the result will be extended to a long
, but that's too late.
Suffix the number with an l
to make it a long
: 2147483647l + 10
.
2200000000
is too big for an int
, therefore it is a long
, so the additon works as expected.
The problem is that 2147483647
is of type int
, not long. So the calculation 2147483647 + 10
overflows and behaviour is undefined . The usual arithmetic conversions convert each operand to
int
int
to the type of the operand having greater rank, and signed is converted to unsigned if of equal rank! Since both operands are int
s the addition happens with int
.
Since 2200000000
does not fit 32-bit int
it will be long
or long long
or ( unsigned int if C89).
Always use a suffix for the integer constants when the size actually matter: l
for longs, u
for unsigned -- and ll
for long long int; these can be coupled and are case sensitive so you can use LL
for it to stand out from the others.
Finally, notice that long int
need not be able to hold numbers greater than 2147483647
either, use long long int
for that.
PS C89 did not have a long long int
type at all, so in C89 vs C99+ the behaviour of the following would be different from each other if used as a constant expression on " long
is 32-bit" machine!
-1 < 2147483647 + 10
It could result in 0 in C89 on 32-bit machine, and 1 in C99+ always.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.