簡體   English   中英

為什么 uint64_t 類型的 -INT_MIN 不是 2147483648

[英]Why -INT_MIN is NOT 2147483648 for uint64_t type

我理解p的結果。 有人可以解釋為什么up2 (uint64_t type) != 2147483648up (uint32_t type) == 2147483648嗎?

有人提到將 -INT_MIN 分配給無符號整數 up2 會導致溢出,但是

  1. -INT_MIN已經是一個正數了,所以可以把它分配給uint64_t up2嗎?

  2. 為什么將-INT_MIN分配給uint32_t up似乎-INT_MIN 它產生正確的結果為 2147483648。

     #include <iostream> #include <climits> using namespace std; int main() { int n = INT_MIN; int p = -n; uint32_t up = -n; uint64_t up2 = -n; cout << "n: " << n << endl; cout << "p: " << p << " up: " << up << " up2: " << up2 << endl; return 0; }

    結果:

     n: -2147483648 p: -2147483648 //because -INT_MIN = INT_MIN for signed integer up: 2147483648 //because up is unsigned int from 0 to 4,294,967,295 (2^32 − 1) and can cover 2147483648 up2: 18446744071562067968 //Question here. WHY up2 != up (2147483648)???

int p = -n;的行為在 2 的補碼系統上未定義(接受您的問題中有錯字; INT_MAX在這樣的系統上總是奇數),因為您的int類型溢出。 所以你的整個程序是未定義的。

這就是為什么您會在許多庫中看到INT_MIN定義為-INT_MAX - 1

請注意,當您由於有符號整數溢出而調用未定義行為時,以下是您所觀察到的行為的最可能解釋:

如果int在您的系統上是 32 位,並且您的系統使用一個補碼或二進制補碼來存儲有符號整數,那么符號位將擴展為 64 位無符號類型的高 32 位。

如果您以 base-16 打印出您的值可能會更有意義。

n = 0x80000000
p=0x80000000
up=0x80000000
up2=0xFFFFFFFF80000000

您看到的是-n轉換為uint64 ,其中溢出不是 40 億,而是 2**64:

18446744073709551616 - 2147483648 = 18446744071562067968

您的情況下的表達式-n會導致未定義的行為,因為結果無法適應int數據類型的范圍。 (無論您是否將此未定義的結果分配給“更寬”類型的變量都無關緊要,反轉本身是用int 。)

試圖解釋未定義的行為是沒有意義的。

暫無
暫無

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

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