3 回答

TA貢獻1871條經驗 獲得超13個贊
-2147483648不是“數字”。C ++語言不支持負文字值。
-2147483648實際上是一個表達式:在其前面2147483648帶有一元運算-符的正文字值。2147483648對于int您的平臺范圍的積極方面,價值顯然太大。如果類型long int有你的平臺上更大的范圍,編譯器將不得不自動假設2147483648有long int型。(在C ++ 11中,編譯器還必須考慮long long int類型。)這將使編譯器-2147483648在較大類型的域中求值,并且結果將為負數,這與預期的一樣。
但是,顯然在您的情況下,范圍與的范圍long int相同int,并且通常不存在比int平臺更大的整數類型。正式地,這意味著正常數會2147483648溢出所有可用的帶符號整數類型,這又意味著程序的行為是不確定的。(在這種情況下語言規范選擇了未定義的行為,而不是要求診斷消息,這有點奇怪,但這就是事實。)
在實踐中,考慮到行為是不確定的,2147483648可能會被解釋為某些依賴于實現的負值,在-對它應用一元后,它會變成正值。或者,某些實現可能會決定嘗試使用無符號類型來表示該值(例如,在C89 / 90中要求使用編譯器unsigned long int,而在C99或C ++中則不需要)。允許執行任何操作,因為無論如何行為都是未定義的。
順便說一句,這就是INT_MIN通常將like常量定義為的原因
#define INT_MIN (-2147483647 - 1)
而不是看似更直接
#define INT_MIN -2147483648
后者將無法按預期工作。

TA貢獻1780條經驗 獲得超4個贊
編譯器(VC2012)提升為可以容納值的“最小”整數。在第一種情況下,signed int(和long int)不能(在應用符號之前),但是unsigned int可以:2147483648具有unsigned int ???? 類型。在第二秒中,您int從強制unsigned。
const bool i= (-2147483648 > 0) ; // --> true
警告C4146:一元減運算符應用于無符號類型,結果仍為無符號
以下是相關的“好奇心”:
const bool b= (-2147483647 > 0) ; // false
const bool i= (-2147483648 > 0) ; // true : result still unsigned
const bool c= ( INT_MIN-1 > 0) ; // true :'-' int constant overflow
const bool f= ( 2147483647 > 0) ; // true
const bool g= ( 2147483648 > 0) ; // true
const bool d= ( INT_MAX+1 > 0) ; // false:'+' int constant overflow
const bool j= ( int(-2147483648)> 0) ; // false :
const bool h= ( int(2147483648) > 0) ; // false
const bool m= (-2147483648L > 0) ; // true
const bool o= (-2147483648LL > 0) ; // false
C ++ 11標準:
2.14.2整數文字[lex.icon]
…
整數文字是沒有句號或指數部分的數字序列。整數文字可以具有指定其基數的前綴和指定其類型的后綴。
…
整數文字的類型是相應列表中可以表示其值的第一個。
如果整數文字不能用其列表中的任何類型表示,并且擴展整數類型(3.9.1)可以表示其值,則它可能具有該擴展整數類型。如果文字列表中的所有類型均已簽名,則擴展整數類型應被簽名。如果文字列表中的所有類型都是無符號的,則擴展整數類型應為無符號的。如果列表同時包含有符號和無符號類型,則擴展整數類型可以是有符號或無符號的。如果程序的翻譯單元之一包含不能用任何允許的類型表示的整數文字,則該程序格式錯誤。
這些是標準中整數的促銷規則。
4.5整體促銷 [conv.prom]
以外的整數類型的prvalue bool,char16_t,char32_t,或 wchar_t,其整數轉換秩(4.13)小于INT的秩可以被轉換成類型的prvalue int如果int可以表示源類型的所有值; 否則,可以將源prvalue轉換為type的prvalue unsigned int。

TA貢獻1829條經驗 獲得超7個贊
由于-2147483648實際上對其應用2147483648了否定(-),因此該數字不是您所期望的。它實際上等效于此偽代碼:operator -(2147483648)
現在,假設您的編譯器具有sizeof(int),4并且CHAR_BIT被定義為8,則將使2147483648溢出成為整數(2147483647)的最大有符號值。那么最大加一是多少?讓我們用一個4位2s的補碼整數來計算。
等待!8溢出整數!我們做什么?使用其無符號表示形式1000并將這些位解釋為有符號整數。這種表示方式使我們得以-8應用2s補碼求反,導致8,眾所周知,它大于0。
這就是為什么<limits.h>(和<climits>)通常定義INT_MIN為((-2147483647) - 1)-,從而使最大有符號整數(0x7FFFFFFF)取反(0x80000001),然后遞減(0x80000000)。
- 3 回答
- 0 關注
- 386 瀏覽
添加回答
舉報