天天看點

C語言中的位移運算

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。
           

繼續閱讀