有符号和无符号整数如何存储在c中?

时间:2012-09-10 11:59:02

标签: c

我正在尝试运行以下代码,但与此处发生的事情相混淆:

int main()
{
 /* 
    a = -1; 
    b = 0xffffffff; 
 */
if(-1 == 0xffffffff )
        printf("-1 is equal to maximum\n");
else
        printf(" -1 is not equal to maximum\n");

if(0xff < -1)
        printf(" Less than -1 \n");
if(0xff < 0xffffffff)
        printf(" Less than maximum\n");

我也尝试了注释部分,用“a”替换-1,用“b”替换0xffffffff但结果相同。

这是32位系统,所以我采用整数4字节。

我的输出是:

-1 is equal to maximum
 Less than maximum

如果-1等于最大值,那么它应该执行最后两个if语句。但它没有发生。为什么呢?

4 个答案:

答案 0 :(得分:5)

我会用C ++引用它;我认为对C来说是一样的:

文字-1始终为signed int

文字0xffsigned int,但0xffffffffunsigned int

在比较混合符号时,两个操作数都转换为无符号,解释所有结果。

这是关于C ++ 11,表6中的裸整数文字类型(即没有类型后缀)的规则:

  • 十进制文字是intlong intlong long int中最小的文字,无论哪个都适合。

  • 十六进制文字是intunsigned intlong intunsigned long intlong long intunsigned long long int中最小的文字,无论哪个适合。

再拼出来:

  • 在您的第一次比较中,双方都转换为unsigned int,给出值0xFFFFFFFF

  • 在第二次比较中,两个字词都是有符号整数,左边的术语是255,右边的术语是-1

  • 在第三次比较中,两个字词都转换为unsigned int


观察我们永远不必担心这个问题的签名的硬件实现。唯一相关的与平台相关的值是int的大小,我们在声明0xffffffff不适合int 适合unsigned int

答案 1 :(得分:1)

在C / C ++中,负数以2的恭维格式存储,而最高有效位(MSB)则用作叹息指示。

MSB 1表示-ve,MSB 0表示+ ve。 1xxxxxxxxxx是-ve number,0xxxxxxxxxx表示+ ve。 在1xxxxxxx中,“xxxxxx”是2的恭维数字。 在0xxxxxx中,“xxxxx”是数字的实际二进制表示。

编译器解释数为-ve,如果MSB(符号位)为1,并且理解该数字必须是两个人的赞美。

首先让我们看看2的恭维:

2的赞美是否定实际数字(所有位)然后加1。

十进制1 = 00000001

〜十进制1 = 11111110

2的十进制补码1 = 11111111(F hex)

所以-1变为= (1) 111111111111111

(1)是一个MSB,表示-ve数,其余是2的数字补码。

因此-1 = 0xFFFFFFFF

您可以尝试打印某些-ve数字的二进制表示,并比较2的数字二进制表示形式的补码。

答案 2 :(得分:0)

0xffffffff等于-1,因为int类型只有四个字节且-1 0xffffffff在内存中为-1 == (~1) + 1-1)。所以编译器无法区分0xffffffff0x000000ff - 在内存中根本没有空间。

255相当于-1,大于if,因此最后两个char c = 0xff; if( c == -1 ) { printf("char 0xff is -1"); } 将无法执行。

你可能会感到困惑的是:

char

在这种情况下,我将intchar进行比较,因此编译器必须扩展8位char类型。由于-1已签名,因此将保留符号(最高位),您将获得{{1}}(int)。

two-complement

这是一个例子,为什么在混合有符号/无符号类型和不同宽度的类型时需要小心。

答案 3 :(得分:0)

首先,您看到的结果与有符号整数的位表示无关,尽管它们与大小有关。

转换为无符号时,值-1将转换为目标类型的最大值。这就是-1 == 0xffffffff的原因。 -1的位表示不会影响任何内容。

0xff < -1为false,因为两个值均已签名int:左侧为255,右侧为-1。

最后,在第一次比较中将-1转换为无符号的原因是0xffffffff对于您的实现上的int 来说太大了(对于大多数情况而言)实现)。但是,它确实适合unsigned int(同样适用于您的实现,以及大多数16位计算机以外的实现)。为了将unsigned int与signed int进行比较,C将signed int转换为unsigned。这给出了令人惊讶的结果(包括-1在某种程度上等于正数的意外),这就是大多数样式指南告诉你避免混合有符号和无符号类型的原因。但改变语言为时已晚。