2013-05-07 40 views
1

我發現一些有線問題,當我嘗試做32次左移時。測試函數中的代碼應該打印出相同的結果0x0,但我得到了「ffffffff,0」。任何人都可以暗示代碼有什麼問題?謝謝!按位左移意外結果

int test(int n) { 
    int mask = ~0 << (32 + ~n + 1); 
    int mask1 = ~0 << (32 + ~0 + 1); 
    printf("%x, %x\n", mask, mask1); 
    return mask; 
} 

int main(){ 
    test(0); 
} 
+0

同樣與http://stackoverflow.com/questions/3784996/why-does-left-shift-operation-invoke-undefined-behaviour-when-the-left-side-oper – MOHAMED 2013-05-07 16:30:07

+0

你可以嘗試製作int聲明一個unsigned int並告訴我們它是否會有所作爲? – 2014-01-07 19:54:14

回答

4

在C中,與(你的情況int)尺寸比型尺寸更大的移位是未定義的行爲

從這topic:從ISO C99相關報價(6.5.7/4)

E1的結果< < E2是E1左移E2位的位置;騰空的比特用零填充。如果E1具有無符號類型,則結果的值是E1×2 E2,減模 比結果類型中可表示的最大值多一個。如果E1有一個有符號的 類型和非負值,並且E1×2 E2可以表示結果類型,那麼就是 的結果值;否則,行爲未定義

+0

您的意思是,如果移動距離與字體大小相同,它仍然是未定義的? – zhengbli 2013-05-07 16:25:48

+0

哦,現在我明白了。謝謝! – zhengbli 2013-05-07 16:28:00

+0

是的。如果你的字體大小爲32,那麼你可以使用數字<= 31 – MOHAMED 2013-05-07 16:28:06

2

假設你有32位整數,左移位超過31倍的結果是不確定的

從C11 §6.5.7 Bitwise shift operators

E1 < < E2的結果E1左移E2位位置;騰空的 位填充了零。如果E1具有無符號類型,則值爲 ,結果爲E1 x 2E2,比結果類型中可表示的最大值 的模數減1。如果E1具有帶符號的類型和非負值,並且E1 x 2E2可在結果類型中表示,則 即爲結果值;否則,行爲是未定義的 。

+0

哦,這個解釋清楚。感謝您的參考! – zhengbli 2013-05-07 16:26:46