(unsigned)~0
和(unsigned)1
之间有什么区别?为什么unsigned
的{{1}}为~0
且-1
的{{1}}为unsigned
?它是否与无符号数存储在内存中的方式有关。为什么无符号数字会给出签名结果。它也没有给出任何溢出错误。我正在使用1
编译器:
1
答案 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()
只知道您在格式字符串中使用的格式说明符传递的变量类型。所以这里发生的是您将x
和y
打印为签名的整数,因为您在格式字符串中使用了%d
。请尝试使用%u
,然后您的结果会更符合您的期望。