我正在尝试运行以下代码,但与此处发生的事情相混淆:
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语句。但它没有发生。为什么呢?
答案 0 :(得分:5)
我会用C ++引用它;我认为对C来说是一样的:
文字-1
始终为signed int
。
文字0xff
是signed int
,但0xffffffff
是unsigned int
。
在比较混合符号时,两个操作数都转换为无符号,解释所有结果。
这是关于C ++ 11,表6中的裸整数文字类型(即没有类型后缀)的规则:
十进制文字是int
,long int
或long long int
中最小的文字,无论哪个都适合。
十六进制文字是int
,unsigned int
,long int
,unsigned long int
,long long int
,unsigned 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
)。所以编译器无法区分0xffffffff
和0x000000ff
- 在内存中根本没有空间。
255
相当于-1
,大于if
,因此最后两个char c = 0xff;
if( c == -1 ) {
printf("char 0xff is -1");
}
将无法执行。
你可能会感到困惑的是:
char
在这种情况下,我将int
与char
进行比较,因此编译器必须扩展8位char
类型。由于-1
已签名,因此将保留符号(最高位),您将获得{{1}}(int)。
这是一个例子,为什么在混合有符号/无符号类型和不同宽度的类型时需要小心。
答案 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在某种程度上等于正数的意外),这就是大多数样式指南告诉你避免混合有符号和无符号类型的原因。但改变语言为时已晚。