2017-02-17 25 views
33

這個問題之前被問過,但我仍然困惑。UINT_MAX是否將所有位都設置爲1?

我知道

unsigned int a = -1; 

UINT_MAX。但這不是因爲所有的位都被設置了。 C11表示

如果新類型是無符號的,所述值是通過反覆增加或 減去一個小於能夠在該新型 來表示直到該值是在新的範圍中的最大值更轉換鍵入

因此,可以說UINT_MAX是100(我知道這應該是大於2^16-1但讓我們忽略這個現在)

unsigned int a = -1; // will be 
unsigned int a = -1 + UINT_MAX + 1; // 100 = UINT_MAX 

標準只說:UINT_MAX >= 2^16-1。但是它說它應該是2^n-1嗎?

C++中的答案也不同嗎?

+6

我認爲這個標準主要留下未指定值(或平臺相關)的確切位表示。那裏有一些非常奇怪的架構。 –

回答

47

在C中,對於一個無符號整數的最大值必須在形式:2 Ñ - 1.

因此,值UINT_MAX的所有比特將被設置爲1.可能有填充位,其值未指定。


(引自:ISO/IEC 9899:201X 6.2.6.2整數類型1)
對於除無符號字符其他無符號整數類型,所述對象的表示的比特必須被分成兩組:值位和填充位(不需要後者中的任何一個)。如果有Ñ值的比特,每個比特應表示2 1和2之間N -1個不同的功率,使得該類型的對象須能從0表示值,以2 Ñ -1使用純二進制表示;這應該被稱爲價值表示。任何填充位的值都是未指定的。

+1

謝謝,這清除了一切。 – taytay

+3

呵呵。我猜你不能爲三元計算機編寫C編譯器。 – Mark

+1

呃...你可能*,它只會吸:P – MickLH

12

不,不是。

無符號類型可以由值位填充位組成。

對於最大值,數值位始終設置爲1是正確的,但填充位的具體值留給實現。所以這意味着UINT_MAX需要是一個梅森編號。其他要求聲明它不能小於65535.

C和C++在這方面是等價的。

+0

但是,這仍然需要UINT_MAX必須是2^n - 1的形式,對於某些n> = 16。 –

+0

的確的確如此:即Mersenne數字(不一定是質數),大於或等於65535. – Bathsheba

+0

我可以' t在C++ 14標準中找到任何關於具有任何填充位的基本類型的東西。我認爲在'[basic.fundamental]'中引用C標準的唯一想法是它必須遵守C 5.2.4.2.1這是限制部分。 – NathanOliver

2

你說對於轉換的定義是正確的,-1轉換爲unsigned int保證是UINT_MAX。它與任何位模式都沒有關係。如果有一個UINT_MAX爲100的實現,則-1轉換爲無符號int將爲100.

UINT_MAX不能爲100的原因有一個:其中一個原因是它必須≥2^16-1,但這樣會允許UINT_MAX = 1,000,000。第二,因爲無符號整型必須具有值的位的某些固定數量n的二進制表示,所以UINT_MAX = 2^N - 1。

可能INT_MAX = 2^31 - 1和UINT_MAX = 2^31 - 1(通常不是2^32 - 1)。在這種情況下,-1會設置32位; -1轉換爲無符號整數將是2^31 - 1,並且只設置了31位。

+0

微小挑剔:-1 + 31位'signed int'中有32位set _if實現使用two's complement_,實際上80年代中期以來的所有機器都是用於整數,但是6.2.6.2p2是_allows_的'complement'或符號和幅度分別具有31位和2位。 –

+0

@ dave_thompson_085:具有32位二進制補碼有符號整數的系統幾乎肯定也會有一個32位無符號整數。一個非設計的實現只有一個「unsigned」類型,其可能值比相應的帶符號類型更少的唯一原因是硬件被限制爲一種無法容納2?個不同值的有符號算術形式。 – supercat

相關問題