长整数算术中的歧义?

时间:2013-02-07 10:22:41

标签: c long-integer integer-arithmetic

看看以下代码:

#include <stdio.h>

int main(void)  
{  
int a;

a = 2147483647;
printf("a + 1 = %d \t sizeof (a + 1) = %lu\n", a + 1, sizeof (a + 1));
printf("a + 1L = %ld \t sizeof (a + 1L) = %lu\n", a + 1L, sizeof (a + 1L));

a = -1;
printf("a + 1 = %d \t sizeof (a + 1) = %lu\n", a + 1, sizeof (a + 1));
printf("a + 1L = %ld \t sizeof (a + 1) = %lu\n", a + 1L, sizeof (a + 1L));  //why a + 1L does not yield long integer ?

return 0;
}  

这导致以下输出:

a + 1 = -2147483648   sizeof (a + 1) = 4  
a + 1L = 2147483648   sizeof (a + 1L) = 8  
a + 1 = 0    sizeof (a + 1) = 4  
a + 1L = 0   sizeof (a + 1) = 8

为什么最后一行a + 1L会产生0而不是长整数为4294967296?

2 个答案:

答案 0 :(得分:5)

  

为什么最后一行中的+ 1L不会产生长整数为4294967296?

因为将int -1转换为long int会导致long int的值为-1,-1 + 1 = 0

如果目标类型是无符号32位类型,则将-1转换为另一种类型只会导致4294967295(通常,unsigned int通常为uint32_t ,如果提供)。但是,在该值中加1将换行为0。

因此,要获得4294967296,您需要一个中间演员,

(uint32_t)a + 1L

以便-1首先转换为uint32_t,其值为4294967295,然后转换为long

答案 1 :(得分:1)

在第一种情况下: 2147483647是32位有符号值,十六进制表示为0x7fffffff。 向它添加1会得到一个32位值,十六进制0x80000000,在32位有符号整数(由于溢出)中为-2147483648,如果被视为64位有符号整数,则为2147483648。

在第二种情况下: -1是32位有符号值,十六进制表示为0xffffffff。 向它添加1会得到一个32位值,十六进制0x00000000,在signed int中为0。

当你在64位中加1时,首先会发生符号扩展,所以你真的添加了0xFFFFFFFFFFFFFFFF和0x0000000000000001,总和是预期的0。

如果您考虑使用符号扩展名,则不会有歧义。