首先談之前需要明白一下幾點:
1 對於數字 在計算機中存貯和計算都是以補碼的形式 正數的補碼和反碼就是它本身 負數的補碼是反碼+1 注意對於有符號的數字 最高位表示符號位 0表示正 1表示負
2 之所以用補碼進行計算和存儲的原因:
1)使符號位能與有效值部分一起參加運算,從而簡化運算規則。從而可以簡化運算器的結構,提高運算速度;(減法運算可以用加法運算表示出來。)
2)加法運算比減法運算更易於實現。使減法運算轉換爲加法運算,進一步簡化計算機中運算器的線路設計。【從補碼運算的特徵理解!】
3)爲了防止0的機器數有兩個編碼。
注意:
http://www.360doc.com/content/12/1009/21/10086564_240513741.shtml
3因此 << >> >>>都是對補碼進行操作 此點重要 byte 和 char在進行移位操作時候 都是轉換爲int進行操作
一:<<表示左移運算
左移的規則只記住一點:丟棄最高位,0補最低位
如果移動的位數超過了該類型的最大位數,那麼編譯器會對移動的位數取模。如對int型移動33位,實際上只移動了1位
舉例正數:4
補碼:0000 0000 0000 0000 0000 0000 0000 0100(正數補碼=原碼)
4<<1
=8 0000 0000 0000 0000 0000 0000 0000 1000 此時雖然丟棄了最高位 但是左移後符號並沒有改變 仍然爲正
---------------------------------------------------------------------
舉例負數:-4
補碼:11111111111111111111111111111100
-4<<1
= -8 11111111111111111111111111111000 (再取反+1就還原爲原碼) 此時雖然丟棄了最高位1 但是左移後符號並沒有改變 仍然爲負
二 >>有符號右移
右移的規則只記住一點:符號位(正負)不變,左邊補上符號位(正數左邊補0 負數左邊補1 有差別 因此叫做有符號右移)
舉例正數:4
補碼:0000 0000 0000 0000 0000 0000 0000 0100(正數補碼=原碼)
4>>1
=2 0|000 0000 0000 0000 0000 0000 0000 0010 符號位置正負不變 |左邊補0
---------------------------------------------------------------------
舉例負數:-4
補碼:11111111111111111111111111111100
-4>>1
= -2 1|1111111111111111111111111111000 (再取反+1就還原爲原碼) 符號位置不變 |左邊補上1
三 >>>無符號右移
無符號右移的規則只記住一點:忽略了符號位擴展,0補最高位 (那麼此時負數的話會帶來正負號變化的問題)
舉例正數:4
補碼:0000 0000 0000 0000 0000 0000 0000 0100(正數補碼=原碼)
4>>>1
=2 0000 0000 0000 0000 0000 0000 0000 0010 忽略符號位 直接在符號位左邊補0
---------------------------------------------------------------------
舉例負數:-4
補碼:11111111111111111111111111111100
-4>>>1
= 2147483646 (由負變正 此時爲正數 補碼以0開頭 正數的原碼 補碼相等 此時補碼就是原碼)
01111111111111111111111111111110 忽略符號位 直接在符號位左邊補0
無符號右移在數據變換時非常重要。
比如對byte b;做無符號右移,在衆多散列、加密、壓縮、影音媒體編碼、序列化格式都會用到。如果沒有這個無符號右移,就需要用更大的空間去做有符號右移。
比如byte就需喲short,short就需要int去做,浪費空間和時間。總之,無符號右移的應用場合大大多於有符號右移。(歡迎補充指正)
此處參考:http://www.zybang.com/question/3666fc8d9c9903e808803ca8781670a2.html
四:爲什麼沒有<<<
從上面可以看出,左移是在右邊補0 不管正數負數 右邊補0 都對符號位不產生影響 不產生符號問題
右移是在左邊補,正數補0 負數補1(都是對補碼而言)
因此沒必要無符號左移 <<<和<<是一樣的概念