簡體   English   中英

C ++隱式數據類型從unsigned轉換為signed

[英]C++ implicit datatype conversion from unsigned to signed

我知道較低的數據類型被轉換為更高的數據類型(例如int - > unsigned int - > float - >等)但我不確定以下內容:

int var = 5u - 10; // var = -5
auto var = 5u - 10; // var = 4294967291

5u是無符號的,但在第一種情況下為什么-10(有符號整數)沒有轉換為無符號值,而在第二種情況下呢? 在第一種情況下,有符號值不會轉換為無符號值,這對我來說很奇怪

沒有“有符號整數文字”: 5u - 10實際上是從5u減去10。

結果(減法)是無符號的,然后溢出,結果給出“比溢出0小5個數字”(4294967291 = 2 32 -5)

第一個語句初始化一個int ,因此無符號編譯時常量被重新解釋為int。 結果是正確的(-5)因為您的硬件使用2s補碼算法。 (-5和4294967291是相同的32位模式)

第二個語句初始化一個變量,其類型由文字推斷。 它沒有unsigned

兩個示例的右側完全在無符號類型的域中工作。 即你的兩個表達式5u - 10表現相同,這並不奇怪,因為它們是相同的。 在任何一種情況下,在5u - 10表達式中都沒有轉換為int (因為你似乎錯誤地假設)。

表達式5u - 10總是在無符號類型的域中求值,並產生等於UINT_MAX + 1 - 5無符號結果。 在第一次初始化中,您嘗試將該值強制轉換為int類型的變量,這會導致實現定義的行為溢出。 在您的情況下,您的實現表現為var獲得值-5 換句話說,你在var-5結尾的事實在抽象C ++語言的領域中沒有明確的解釋。 您觀察到的結果只是編譯器的一個怪癖。 在某些其他編譯器中,第一次初始化可能會在var生成不同的值。

在第二種情況下,表達式的類型(同樣, unsigned )成為變量的類型,使用無符號值初始化而沒有任何溢出。

首先,因為您使用auto ,編譯器將在您的第二個示例中選擇unsigned

有符號和無符號的數字在內部以相同的方式存儲。 它只是在打印時解釋數字的方式產生差異[並且在比較中,因為“否定”有符號數字低於0,無符號數字不能小於零] - 檢查有符號數字如果它們是“否定的”,則打印為減號和否定的原始數字。 無符號數字僅被視為內部表示在打印時變為的任何內容。

因此,您看到的值只是相同數字的兩個不同表示 - 分別是有符號和無符號。

在C和C ++中,在絕大多數情況下,表達式的類型是從表達式本身確定的,而不考慮它出現的上下文。

int var = 5u - 10;

5uunsigned int類型; 10int類型。 -運算符的規則使int參數轉換為unsigned int ,使表達式等效於5u - 10u 結果是UINT_MAX + 1 - 10 ,一個非常大的數字。 初始化隱式地將它從unsigned int轉換為signed int 由於該值(幾乎可以肯定)不能表示為int ,因此轉換的結果是實現定義的。 在幾乎所有現有的實現中,轉換只是將無符號表示重新解釋為有符號值,從而得到-5 (這適用於對負值使用二進制補碼表示的系統;由此產生的有符號/無符號轉換的簡單性是二次補碼如此廣泛使用的原因之一。)

請注意, var不可能具有值4294967291 ; int可以在您的系統上保存的最大值(可能) 2147483647

auto var = 5u - 10;

以與之前相同的方式評估5u - 10 ,從而在系統上產生UINT_MAX + 1 - 54294967291unsigned int結果。 auto表示var采用表達式的類型unsigned int ,因此不執行轉換。 (在具有16位int的系統上,結果將為65531

在回答您的問題時,在兩種情況下,常量10 int轉換為unsigned int

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM