2011-04-25 131 views
4

雖然下面的兩個代碼片段在查找變量的操作方面略有差異,但輸出結果似乎相同。爲什麼這樣?代碼片段差異

第一個片段

#include<iostream> 
    using namespace std; 
    int main() 
    { 

    int number = 3,find; 
    find = number << 31; 
    find *= -1; 
    cout << find; 
    return 0; 
    } 

第二摘錄

#include<iostream> 
    using namespace std; 
    int main() 
    { 
    int number = 3,find; 
    find = number << 31; 
    find *= 1; 
    cout << find; 
    return 0; 
    } 

輸出兩個片段:

-2147483648 

(根據Ideone:12

+0

機器上的int大小是多少? 32位?我的猜測是,如果你將它轉移了30位,那麼你應該得到不同的結果。 – matcheek 2011-04-25 09:13:59

+1

請參閱此[問題](http://stackoverflow.com/questions/3784996/why-does-left-shift-operation-invoke-undefined-behaviour-when-the-left-side-opera)。你正在調用未定義的行爲。 – Mat 2011-04-25 09:15:41

+0

@ matcheek:是的,它是32,但無法弄清楚如果將問題的目標更改爲30,問題的目標如何得到滿足。 – NirmalGeo 2011-04-25 09:18:21

回答

4

在這兩個樣本後,假設32位int S,你是在調用未定義行爲作爲Why does left shift operation invoke Undefined Behaviour when the left side operand has negative value?

爲什麼指出?因爲number是帶有32位存儲的簽名int(3<<31)在該類型中不可表示。

一旦你處於未定義的行爲領域,編譯器可以隨心所欲。

(你不能依賴以下任何因爲它是UB - 這只是你的編譯器看起來在做什麼的觀察)。

在這種情況下,它看起來像編譯器正在做右移,導致0x80000000作爲二進制表示。這恰好是INT_MIN的二進制補碼錶示。所以第二個片段並不奇怪。

爲什麼第一個輸出的是同樣的東西?在二進制補碼中,MIN_INT將是-2^31。但最大值是2^31-1MIN_INT * -1將是2^31(如果它是可表示的)。並猜測會有什麼代表性? 0x80000000。回到你開始的地方!