'(无符号)1'和'(无符号)〜0'之间的区别

时间:2013-09-30 01:21:07

标签: c operators bitwise-operators

(unsigned)~0(unsigned)1之间有什么区别?为什么unsigned的{​​{1}}为~0-1的{​​{1}}为unsigned?它是否与无符号数存储在内存中的方式有​​关。为什么无符号数字会给出签名结果。它也没有给出任何溢出错误。我正在使用1编译器:

1

4 个答案:

答案 0 :(得分:5)

因为%d是一个有符号的int说明符。使用%u

在我的机器上打印4294967295

正如其他人所提到的,如果您将最高的无符号值解释为已签名,则得到-1,请参阅two's complement的维基百科条目。

答案 1 :(得分:1)

您的系统使用two's complement表示负数。在此表示中,由所有1组成的二进制数表示最大的负数-1

由于反转零的所有位为您提供由所有1组成的数字,当您通过使用{打印将数字作为带符号的数字时,您得到-1 {1}}需要签名的号码,而不是未签名的号码。

答案 2 :(得分:1)

首先,在您使用printf时,您告诉它将数字打印为带符号(“%d”)而不是无符号(“%u”)。

其次,你说得对,它“与数字存储在内存中的方式有​​关”。 int(有符号或无符号)不是计算机上的单个位,而是k位的集合。 k的确切值取决于您的计算机体系结构的细节,但最有可能的是k = 32。

为了简洁起见,我们假设你的整数是8位长,所以k = 8(除非你正在研究一个非常有限的嵌入式系统,否则肯定不是这种情况)。在那种情况下(int)0实际上是00000000,而(int)~0(否定所有位)是11111111。

最后,在二进制补码(这是有符号数的最常见二进制表示)中,11111111实际为-1。有关两个补码的说明,请参阅http://en.wikipedia.org/wiki/Two's_complement。

如果您将打印更改为使用“%u”,则它将打印一个表示(2 ^ k-1)的正整数,其中k是整数中的位数(因此可能会打印4294967295)。

答案 3 :(得分:0)

printf()只知道您在格式字符串中使用的格式说明符传递的变量类型。所以这里发生的是您将xy打印为签名的整数,因为您在格式字符串中使用了%d。请尝试使用%u,然后您的结果会更符合您的期望。