我在這裏假設32位int
。
C++使添加用戶定義的轉換變得複雜,但讓我們假設用戶定義的轉換沒有在這裏考慮。
有關整數大多數算術運算(例如,不移位),你會得到如下的轉換(這是從內存...):
每個操作數轉換爲int
如果是窄而不是int
,其類型的所有值都可以由int
表示。
如果每個操作數比unsigned
窄,則轉換爲unsigned
。
然後,如果其中一個類型更寬,則每個操作數都會轉換爲更寬類型的兩個操作數類型。
如果它們寬度相同,但是一個是無符號的,那麼選擇無符號類型。
前兩個步驟被稱爲「整數提升」,後兩個步驟是「常規算術轉換」的一部分。
所以,如果你想要做的64位乘法,
int x, y;
// Always done with int
int r = x * y; // 32-bit
// These are always done with int64_t
int64_t r = (int64_t)x * y;
int64_t r = x * (int64_t)y;
int64_t r = (int64_t)x * (int64_t)y;
// This is a 32-bit multiplication, you probably don't want this...
// The RESULT is converted to 64 bit
int64_t r = x * y; // 32-bit
// Same thing...
int64_t r = (int64_t)(x * y); // 32-bit
減法恰好相乘的結果,因此,如果相乘結果是64位的,則減法將有64位完成。
不過:只要你用溢出整數運算,結果是不確定的!這意味着如果x * y
溢出,編譯器可以執行任何想要的操作。也許它會給你帶來64位的結果。也許它崩潰了。也許它格式化你的硬盤。也許事情在你的程序中表現得很奇怪。
在實踐中,這是「有限的未定義的行爲」,所以它可能只會導致你撓頭而詛咒,而不是徹底崩潰你的程序。
: 「窄」 在技術上並不在標準中使用的術語。
'(intA * intB)'總是以'int'精度執行。如果有一些輸出代碼不理解,請發佈[MCVE](http://stackoverflow.com/help/mcve)以及預期輸出和實際輸出。請注意,有符號整數溢出可能會導致*未定義行爲*,在這種情況下可能會發生任何輸出。 –
您的編譯器可能會將這些值乘以64位寄存器,因此似乎可行,但不能保證該行爲。 – paddy
如果溢出,則爲UB。一個可能的UB(在無限多的可能性中)是「表現得好像操作數被轉換爲'int64_t'」。 –