不少类似的问题已经被问过,但它仍然令我感到困惑如何未签名的-1 = -1签署
unsigned int a = -1;
int b = ~0;
if (a == b)
printf("%u\t%d", a, b);
回报
4294967295 -1
我明白值是如何存储在C中,为什么它显示这些数字,但我的问题是,a==b
如何在这里返回true
?
不少类似的问题已经被问过,但它仍然令我感到困惑如何未签名的-1 = -1签署
unsigned int a = -1;
int b = ~0;
if (a == b)
printf("%u\t%d", a, b);
回报
4294967295 -1
我明白值是如何存储在C中,为什么它显示这些数字,但我的问题是,a==b
如何在这里返回true
?
通过混合有符号无符号比较的规则,a == b
等价于a == (unsigned) b
,即比较在无符号类型的域中执行。
~0
的结果是全1位模式。在有符号整数类型中,这个模式在2的补码平台上代表-1
。这意味着您已使用-1
初始化您的b
(经您的printf
确认)。
所以,你的比较实际上是(unsigned) -1 == (unsigned) -1
。难怪它是真实的。
但请记住,相等仍然依赖于实现,因为它取决于2的补码表示的属性。只要C语言正式支持替代符号整数表示(符号和大小,1的补码),平等就取决于它。
而是说比较是在无符号类型的域中执行的,你应该说比较是一点一点的。实际上,在二进制补码表示中,十六进制a等于0xFFFFFFFF(32位平台),数学上等于-1 =( - 2^31 + 2^31-1)=(0xFFFFFFFF)。并且b =〜0使得所有位都被设置为1,即十六进制b = 0xFFFFFFFF。这解释了如果条件返回true。 – shamba
@shamba:绝对不是!恰恰相反,C语言根据C语言的规则进行比较,而不是“一点一滴”。在C中没有“一点一滴”的比较。在这种情况下,我们很幸运,因为我们使用2的补码机器,其中有符号的'〜0'产生'-1'。在1的补码机器上,'〜0'不会产生'-1'(那里'0xFFFFFFFF'为“负零”),并且等式不会成立,即使底层的原始表示仍然会“一点一点地匹配” 。 – AnT
@AnT你能否参考一些材料?参考比较等于'(无符号)-1 ==(无符号)-1'。我明白b怎么变成-1,已经知道了,但比较呢? – Paulo
因为您似乎正在使用它,所以我添加了C标记。 –
为什么它与上面链接中的问题不同,是无符号变量初始化为'-1' - 一个负值。这里的问题是关于比较 – Paulo