2015-04-23 53 views
-1

給出爲什麼轉變INT A = 1至左31位,然後向右31位,成爲-1

int a = 1;00000000000000000000000000000001),

我所做的只是

a=(a<<31)>>31; 

我假設a應該仍然是1之後(我認爲沒有什麼改變)。然而,它結果是-111111111111111111111111111111111)。有人知道爲什麼

+3

查找符號擴展名。然後再用一個unsigned int再試一次。 – ClickRick

+0

if'unsigned int a = 1'then everything everything right –

+0

答案指的是運算符'>>>',它絕對不是C++運算符,所以我不認爲它是重複的。 –

回答

4

你缺少的是在C++右移>>是實現定義的。它可以是有符號值的邏輯或算術平移。在這種情況下,它將從左側移動1以保留移位值的符號。通常情況下,您希望避免在已簽名的值上進行轉換,除非您確切知道他們會是積極的或者轉換實施無關緊要。

+0

'1 << 31'也是實現定義的([ref](https:// stackoverflow。COM /問題/ 26331035 /爲什麼 - 是-1-31-改變將要-實現定義式14)) –

1

「但它原來是-1

您使用unsigned int爲只看到32比0更大的位值這麼做:

unsigned int a = 1; 
a=(a<<31)>>31; 
0

它是一個有符號的移位,所以最左邊的位將被擴展。這樣整體數字就在0的同一側。

通過左移這麼多,您將最低位放入符號位並以負數結束。

當你做一個右移,它的符號擴展,將符號位複製到低31位。

如果你想知道最低位只是做& 1

3

看看它在步驟:

#include <cstdio> 
using namespace std; 

int main() 
{ 
    int a = 1; 
    printf("%d = %x\n", a, a); 
    a <<= 31; 
    printf("%d = %x\n", a, a); 
    a >>= 31; 
    printf("%d = %x\n", a, a); 
    return 0; 
} 

輸出:

1 = 1 
-2147483648 = 80000000 
-1 = ffffffff 

1得到轉移一路攀升至高位,這使得它負數。向後移動觸發器會延長簽名以保持負面。

將a的聲明更改爲unsigned int a,您將獲得您期望的行爲。