java的移位操作詳解,左移和右移

首先要明白一點,

這裏面所有的操作都是針對存儲在計算機中中二進制的操作,那麼就要知道,正數在計算機中是用二進制表示的,負數在計算機中使用補碼錶示的。

左移位:<<,有符號的移位操作
左移操作時將運算數的二進制碼整體左移指定位數,左移之後的空位用0補充


右移位:>>,有符號的移位操作
右移操作是將運算數的二進制碼整體右移指定位數,右移之後的空位用符號位補充,如果是正數用0補充,負數用1補充。

例子:

public static void main(String[] args)
{

System.out.println(3<<2);//3左移2位
System.out.println(-3<<2);//-3左移2位

System.out.println(6>>2);//6右移2位
System.out.println(-6>>2);//-6右移2位

}

輸出結果

12
-12
1
-2
下面解釋一下:

    00000000 00000000 00000000 00000011 +3在計算機中表示
00000000 00000000 00000000 0000001100 左移2位,補0,結果爲12

----------------------------------------------------------------------------------------------

    00000000 00000000 00000000 00000011 +3在計算機中表示
11111111 11111111 11111111 11111100
11111111 11111111 11111111 11111101 -3在計算機中表示
11111111 11111111 11111111 1111110100 左移2位,補0,結果爲負數,就是補碼了,求原碼
10000000 00000000 00000000 00001011
10000000 00000000 00000000 00001100 結果-12
----------------------------------------------------------------------------------------------

這也說明了一個問題:在計算機中,以1開頭的就是補碼的形式,是負數。

    00000000 00000000 00000000 00000110 +6在計算機中表示方法
0000000000 00000000 00000000 00000110 右移兩位,正數補0,結果爲1
----------------------------------------------------------------------------------------------

   00000000 00000000 00000000 00000110 +6在計算機中表示方法
11111111 11111111 11111111 11111001
11111111 11111111 11111111 11111010 -6在計算機中的表示
1111111111 11111111 11111111 11111010 右移兩位,結果爲負數
1000000000 00000000 00000000 000001
1000000000 00000000 00000000 000010 結果爲-2
這個地方很容易弄混,多想幾次就會慢慢理解了。

上面解釋了帶符號的移位操作,下面解釋一下不帶符號的移位操作

無符號的移位只有右移,沒有左移使用“>>>”進行移位,都補充0

例如:
public static void main(String[] args)
{
System.out.println(6>>>2);
System.out.println(-6>>>2);

}
結果:

1
1073741822

分析:

   00000000 00000000 00000000 00000110 +6在計算機中表示方法
0000000000 00000000 00000000 00000110 右移兩位,正數補0,結果爲1
-----------------------------------------------------------------------------------------------------

   00000000 00000000 00000000 00000110 +6在計算機中表示方法
11111111 11111111 11111111 11111001
11111111 11111111 11111111 11111010 -6在計算機中的表示
0011111111 11111111 11111111 11111010 右移兩位,補充0,結果爲1073741822

 

以下來自:http://jefflee.javaeye.com/blog/203863

可以參考

移位操作要注意的問題是高(低)位是補0還是補1和對char, byte, short型的操作:
(1)<< : (left-shift), 最低位補0
(2)>> : (signed right-shift), 右移過程使用符號位擴展(sign extension),即如果符號爲爲1則高位補1, 是0則補0,也就是邏輯右移
(3)>>> : (unsigned right-shit),右移過程使用零擴展(zero extension),即最高位一律補0,也就是算術右移
(4)移位操作的數據類型可以是byte, char, short, int, long型,但是對byte, char, short進行操作時會先把它們變成一個int型,最後得到一個int型的結果,對long型操作時得到一個long型結果,不可以對boolean型進行操作。
(5)移位操作符可以和=合併起來,即 <<= 、 >>= 和 >>>=。例如 a >>= 2; 表示將a右移兩位後的值重新賦給a。當時在使用這三個操作符對 byte, char, short型數據進行操作時要注意,例如有一下代碼片段:

public class ShiftTest
{
public static void main(String [] args)
{
byte a;
byte b;
byte c;
a
 = 127;
b
 = 127;
c
 = 127;
a
 <<= 2;
System.out.println(a);
System.out.println(b
 <<= 2);
System.out.println(c
 << 2);
}
}

運行結果是:
-4
-4
508
這說明了在操作a <<= 2 執行過程是這樣的:先將 byte型的數 127變成int型,左移2位得到 508,然後把508賦給byte型變量a時只是簡單地"折斷"(truncate)得到數-4。編譯時編譯器不會提示你可能損失精度(實際上在本例中確實是損失精度了),但是如果你把a <<= 2改成 a = a << 2;編譯器就會提示可能損失精度了。

 

================================================================================

移位操作的簡單計算方法

>>右移操作

x>>y

就是x除以2的y此方,取整數

<<左移操作

X<<y

就是x乘以2的y次方


================================================================================

要把這個數二進制化就能理解了。如十進制的2,二進制表示是0010。2左移3位,就是在二進制的低位補3個0,然後變成00010000,轉成十進制就是16,即2*2^3。右移也是一樣的理解就好了。
右移的話要分帶符號位和不帶符號位兩種。
計算機中的數都是二進制表示的,以8位的byte類型表示爲例,5可以表示爲:00000101(最高位表示符號,0位正,1爲負)
無論>>還是>>>都是針對二進制數進行操作的。
1、右移運算符>>使指定值的所有位都右移規定的次數。右邊移出去的部分扔掉不要,左邊空出來的部分用原來的數字填充(這就是所謂的帶符號右移)
——比如說5,右移後爲00000010。
——你給的例子,假設x=-12,表示爲32位int型就是
11111111111111111111111111110100 
x>>3即帶符號右移3位,結果是
11111111111111111111111111111101,化爲十進制等於-3
2、>>>與>>唯一的不同是它無論原來的最左邊是什麼數,統統都用0填充。
——比如你的例子,byte是8位的,-1表示爲byte型是11111111(補碼錶示法)
b>>>4就是無符號右移4位,即00001111,這樣結果就是15。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章