问题描述
我在Linux 3.10.0-957.5.1.el7.x86_64,g ++版本4.8.5中编译了以下源代码
案例1:
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");
编译警告:
warning: integer overflow in expression [-Woverflow]
lx1=2147483647 + 10 ;
并输出:
INT_MAX=(2147483647),INT_MIN=(-2147483648)
ix is bigger
和以下源Case2:
printf("INT_MAX=(%d),lx2=0;
lx1=2200000000 + 10 ;
lx2=2100000000 ;
if( ix < (lx1-lx2) )
printf("ix is not bigger \n");
else
printf("ix is bigger \n");
编译时没有警告,输出:
INT_MAX=(2147483647),INT_MIN=(-2147483648)
ix is not bigger
我的问题:为什么Case1输出可能是错误的? lx1和lx2均为long int,在此框中为8字节大小,为什么2200000000可以,但是2147483647不适用于lx1吗?!
Comparing int with long and others 被引用,仍然无法弄清楚。
解决方法
2147483647 + 10
的计算使用int
数据类型进行,因为两个值都适合int
。结果溢出,然后将结果扩展到long
,但这为时已晚。
在数字后加上l
,使其成为long
:2147483647l + 10
。
2200000000
对于int
而言太大,因此它是long
,因此添加项可以按预期工作。
问题是2147483647
的类型为int
,时间不长。因此,2147483647 + 10
计算溢出,并且行为为未定义。通常的算术转换将每个操作数转换为
-
int
- 或者如果不能在
int
中表示为具有更高等级的操作数的类型,并且如果等级相等,则将有符号转换为无符号!
由于两个操作数均为int
,所以加法运算发生在int
上。
由于2200000000
不适合32位int
,因此它将是long
或long long
或(如果是C89,则为 unsigned int )。
当大小实际上很重要时,始终对整数常量使用后缀:l
代表long,u
代表unsigned-和ll
代表long long int;它们可以耦合并且区分大小写,因此您可以使用LL
使其与众不同。
最后,请注意,long int
也不必容纳大于2147483647
的数字,为此请使用long long int
。
P.S。 C89根本没有long long int
类型,因此在C89与C99 +中,如果在“ long
是32位”机器上用作常量表达式,则以下行为会彼此不同!
-1 < 2147483647 + 10
在32位计算机上,C89中的结果可能为0,而在C99 +中则始终为1。