2013-09-30 156 views
1

(unsigned)~0(unsigned)1有什麼區別?爲什麼unsigned~0-1unsigned11?它是否與無符號數字存儲在內存中的方式有​​關。爲什麼一個無符號數給出了一個簽名結果。它也沒有給出任何溢出錯誤。我使用GCC編譯:'(無符號)1'和'(無符號)〜0'之間的區別

#include<sdio.h> 
main() 
{ 
unsigned int x=(unsigned)~0; 
unsigned int y=(unsigned)1; 
printf("%d\n",x); //prints -1 
printf("%d\n",y); //prints 1 
} 
+0

不是'〜0'的行爲是依賴於實現的讀取:[在C中計算數據類型的範圍](http://stackoverflow.com/questions/17796041/calculating-ranges-of-data-types-in-c/17796122#17796122) –

回答

5

因爲%d是一個符號整數說明符。使用%u。我的機器上打印4294967295

正如其他人所提到的,如果您將最高的無符號值解釋爲有符號值,您將得到-1,請參閱維基百科條目two's complement

+0

哦謝謝!爲什麼它不是1而是4294967295 – programer8

+0

,因爲運算符會反轉*所有位。 –

+0

'〜'是一個按位不操作符,並翻轉所有位。也許你正在想'''(邏輯不是),這可能會給你1。 – Dmitri

1

您的系統使用負數表示two's complement。在這種表示中,由所有1組成的二進制數表示最大的負數-1

由於反轉零的所有位爲您提供了所有的人組成的號碼,你會得到-1當你通過與%d一個希望將簽署號印字它重新詮釋作爲有符號數數,不是未簽名的。

+0

哦謝謝解釋。 – programer8

0

printf()只知道通過格式字符串中使用的格式說明符傳遞的變量類型。所以這裏發生的是你正在打印xy作爲簽署整數,因爲你在你的格式字符串中使用了%d。改爲嘗試%u,你會得到一個更符合你可能期望的結果。

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的補充說明二進制補碼。

如果你改變你的打印使用「%u」,那麼它將打印一個正整數,表示(2^k-1)其中k是整數中的位數(所以可能會打印4294967295) 。

相關問題