1. 程式人生 > >Java基礎之 移位操作

Java基礎之 移位操作

移位運算子就是在二進位制的基礎上對數字進行平移。按照平移的方向和填充數字的規則分為三種:
    <<(左移)、>>(帶符號右移)和>>>(無符號右移)。
  在移位運算時,byte、short和char型別移位後的結果會變成int型別,對於byte、short、char和int進行移位時,規定實際移動的次數是
    移動次數和32的餘數,也就是移位33次和移位1次得到的結果相同。移動long型的數值時,規定實際移動的次數是移動次數和64的餘數,
    也就是移動66次和移動2次得到的結果相同。
  三種移位運算子的移動規則和使用如下所示:
 
 <<運算規則:按二進位制形式把所有的數字向左移動對應的位數,高位移出(捨棄),低位的空位補零。
  語法格式:
  需要移位的數字 << 移位的次數
  例如: 5<<1,則是將數字5左移1位
  計算過程:
  5<<1
  首先把5轉換為二進位制數字0000 0000 0000 0000 0000 0000 0000 0101,然後把該數字高位(左側)的兩個零移出,其他的數字都朝左平移1位,
    最後在低位(右側)的一個空位補零。則得到的最終結果是0000 0000 0000 0000 0000 0000 0000 1010,則轉換為十進位制是10.數學意義:
  在數字沒有溢位的前提下,對於正數和負數,左移一位都相當於乘以2的1次方,左移n位就相當於乘以2的n次方。
  -5<<1 =-10
    
 >>運算規則:按二進位制形式把所有的數字向右移動對應的位數,低位移出(捨棄),高位的空位補符號位,即正數補零,負數補1.
 如果最高位是0,那麼左邊最高位就補0; 如果最高位是1,那麼左邊最高位就補1(負數要用補碼,正數補碼跟原碼一樣)  

  語法格式:
  需要移位的數字 >> 移位的次數
  例如5>>2=1,則是將數字5右移2位
  計算過程:5的二進位制形式為:0000 0000 0000 0000 0000 0000 0000 0101,然後把低位的最後兩個數字移出,因為該數字是正數,所以在
    高位補零。則得到的最終結果是0000 0000 0000 0000 0000 0000 0000 0001.轉換為十進位制是1.
    數學意義:右移一位相當於除2,右移n位相當於除以2的n次方(不能整除的用取整)。
    例如-5>>2=-2 則是將數字-5右移2位   
    計算過程:

   -5的二進位制形式:1000 0000 0000 0000 0000 0000 0000 0101

         轉換成補碼:1111 1111 1111 1111 1111 1111 1111 1011

       移位高位補1:1111 1111 1111 1111 1111 1111 1111 1110

      再轉換成原碼:1000 0000 0000 0000 0000 0000 0000 0010

       得到結果-2

 心得:正數右移時是取整,負數右移時是四捨五入取整。


 >>>運算規則:按二進位制形式把所有的數字向右移動對應位數,低位移出(捨棄),高位的空位補零。對於正數來說和帶符號右移相同,對於負數來說不同。
  其他結構和>>相似。
    -5>>>2 = 2^30-2
    原碼  1000 0000 0000 0000 0000 0000 0000 0101
    補碼  1111 1111 1111 1111 1111 1111 1111 1011
 無符號右移兩位  0011 1111 1111 1111 1111 1111 1111 1110 +2-2
   0100 0000 0000 0000 0000 0000 0000 0000 -2 = 2^30-2

    5>>>2=1 和5>>2 相同 
     
  在Thinking in Java第三章中的一段話:
  移位運算子面向的運算物件也是
  二進位制的“位”。可單獨用它們處理整數型別(主型別的一種)。左移位運算子(<<)能將運算子左邊的運算物件向左移動運算子右側指定的位數(在低位補0)。 “有符號”右移位運算子(>>)則將運算子左邊的運算物件向右移動運算子右側指定的位數。“有符號”右移位運算子使用了“符號擴充套件”:若值為正,則在高位插入0;若值為負,則在高位插入1。Java也添加了一種“無符號”右移位運算子(>>>),它使用了“零擴充套件”:無論正負,都在高位插入0。這一運算子是C或C++沒有的。
  若對char,byte或者short進行移位處理,那麼在移位進行之前,它們會自動轉換成一個int。只有右側的5個低位才會用到。這樣可防止我們在 一個int數裡移動不切實際的位數。若對一個long值進行處理,最後得到的結果也是long。此時只會用到右側的6個低位,防止移動超過long值 裡現成的位數。但在進行“無符號”右移位時,也可能遇到一個問題。若對byte或 short值進行右移位運算,得到的可能不是正確的結果(Java 1.0和Java 1.1特別突出)。它們會自動轉換成int型別,並進行右移位。但“零擴充套件”不會發生,所以在那些情況下會得到-1的結果。