2012-08-30 50 views
0

我正在學習C語言。我有這樣的代碼,更可在需要時提供:當我用GDB和打印/x mask1>>移位操作符不按預期方式工作

int result = 0; 
int mask1 = 0x0000ffff; 
mask1 = mask1 >> 28; 

,我得到0x0,這是正確的。 那麼爲什麼:

int result = 0; 
int mask1 = 0xffffffff; 
mask1 = mask1 >> 28; 

print 0xffffffff 

應該不是被打印0x0000000f,因爲我左移28位?

它與我在64位機器上佔用的位數有關嗎? 我看着this,但它並沒有完全回答。

+3

將'mask1'設爲'unsigned int',您將體驗到您期望的行爲(即邏輯右移)。 – oldrinb

+0

@veer謝謝。那樣做了。 – Clara

+0

閱讀實用的程序員,這本書有一個標題爲「選擇不壞」的部分。它描述了你遇到的問題。 – Incognito

回答

5

對負整數的右移行爲是實現定義的。一種常見的行爲是算術移位,它符號擴展。這樣做的好處是,右移也可以被二的冪(四捨五入爲負無窮)劃分,就像正數一樣。

0

如果您打印0xffffffff作爲整數,您會意識到它被視爲-1。

Bitshift與負數的工作方式不同,因爲它用1填充最高位。所以基本上,0xffffffff >> 1 == 0xffffffff。

如果你聲明掩碼爲unsigned int,那麼它可能會做你想做的。

1

您正在轉移。這是正確的:>>,這是遺漏的:<<

通常情況下,當你轉向一個(簽字)整數權,你認爲可以改變但不是標誌:這就是丹尼爾指符號擴展。這不是標準所要求的,並非所有平臺都這樣做。

實際上,在使用二進制補碼的系統中,這意味着負值將會使新的最高位填充1,正值和0

例如,一個8位的二進制補碼系統上:

before   after >> 1 
11111110 = -2 11111111 = -1 (so new top bit was 1) 
00000010 = +2 00000001 = +1 (so new top bit was 0) 
+0

將負整數右移的結果是實現定義的。不保證保持負面。 – Nemo

+0

確實,即將編輯 – Useless

0

是的,作爲@veer指出,與int你在做一個算術右移這對於以2的冪將有符號數(在二進制補碼錶示)是偉大的:

Right arithmetic shift

通過改變類型unsigned int它將成爲一個右鍵按位移位這是偉大的以2的冪除以無符號數(這是您的方案):

Right logical shift

一些優秀的解釋是Wikipedia Bitwise operation