C語言提供了一組位移運算,C表達式x<<k會生成一個值,x向左移動k位,丢棄最高的k位,并在右端補k個0,移位運算時從左至右可結合的,是以x<<k<<j等價于(x<<k)<<j。
還有一個相應的右移運算x>>k,但它的行為有點微妙,一般而言機器支援兩種形式的右移:邏輯右移和算術右移。邏輯右移是在左端不k個0,算術右移是在左端補k個最高有效位的值,邏輯右移和算術右移在對有符号整數資料的位移操作中非常有用,如
操作 | 值 | 值 |
參數x | 01100011 | 10010101 |
x<<4 | 00110000 | 01010000 |
x>>4(邏輯右移) | 00000110 | 00001001 |
x>>4(算術右移) | 00000110 | 11111001 |
唯一的例外就是算術右移[10010101]的情況,因為操作數的最高位是1,填充的值就是1。(簡單粗暴點記憶就是最高位符号位為0都填0,最高符号位為1就都填1)
C語言标準并沒有明确定義應該使用哪種類型的右移。對于無符号資料(unsigned聲明),右移必須是邏輯的。而對于有符号資料,算術位移或者邏輯位移都可以,不幸的是這意味着兩種都有可能,造成代碼的潛在性可移植問題。然而實際上,幾乎所有的編譯器/機器組合度對有符号資料使用算術右移,且許多程式員也都假設機器會使用算術右移。
java對如何右移有明确定義,表達式x>>k表示将x算術右移k個位置,表達式x>>>k表示将x邏輯右移k個位置。
另如果x>>k中k是個很大的值時,許多機器會以x實際所占位對k求餘,x為w位,實際右移k mod w位,在32位機器上執行int x>>36時,實際移動為int x>>4。