1. 程式人生 > >對於Thinking In Java中byte,short無符號右移的理解

對於Thinking In Java中byte,short無符號右移的理解

拜讀Thinking In Java看到以下內容

若對char,byte或者short進行移位處理,那麼在移位進行之前,它們會自動轉換成一個int。只有右側的5個低位才會用到。這樣可防止我們在一個int數裡移動不切實際的位數。若對一個long值進行處理,最後得到的結果也是long。此時只會用到右側的6個低位,防止移動超過long值裡現成的位數。

//對於上面的話 可以看成移動的實際位數 是 給定的移動位數%資料型別的位數

eg.

*int x = 100;
*    x << 35;//結果是800

*a:1100100//二進位制補碼

*35:100011//二進位制補碼,int型別取5個低位00011即3(相當於35%32=3)

*結果:1100100000//800

但在進行“無符號”右移位時,也可能遇到一個問題。若對byte或short值進行右移位運算,得到的可能不是正確的結果(Java 1.0和Java 1.1特別突出)。它們會自動轉換成int型別,並進行右移位。但“零擴充套件”不會發生,所以在那些情況下會得到-1的結果。可用下面這個例子檢測自己的實現方案:

//

//: URShift.java
// Test of unsigned right shift

public class URShift {
  public static void main(String[] args) {
    int i = -1;
    i >>>= 10;
    System.out.println(i);//4194303
long l = -1; l >>>= 10; System.out.println(l);//18014398509481983 //上面兩個好理解 short s = -1; s >>>= 10; System.out.println(s);//-1 byte b = -1; b >>>= 10; System.out.println(b);//-1 //這兩句不理解然後寫了下面一段程式碼 } } ///:~

                for (int i = 1; i < 32; i++) {
			byte s = -1;
			s >>>= i;
			System.out.println(i + " " + s);
//結果是:1 -1 2 -1 3 -1 4 -1 5 -1 6 -1 7 -1 8 -1 9 -1 10 -1 11 -1 12 -1 13 -1 14 -1 15 -1 16 -1 17 -1 18 -1 19 -1 20 -1 21 -1 22 -1 23 -1 24 -1 //25 127 26 63 27 31 28 15 29 7 30 3 31 1 //為了省版面好亂 就是直到>>>25  s的結果才不再是-1
			// System.out.println(Integer.toBinaryString(s));
		}

想了想覺得應該是>>>= 這個寫法的事 於是又寫了以下

byte s = -1;
int ss = s >>> i;
System.out.print(i + " " + ss + " ");
//結果是:1 2147483647 2 1073741823 3 536870911 4 268435455 5 134217727 6 67108863 7 33554431 8 16777215 9 8388607 10 4194303 11 2097151 12 1048575 13 524287 14 262143 15 131071 16 65535 17 32767 18 16383 19 8191 20 4095 21 2047 22 1023 23 511 24 255 25 127 26 63 27 31 28 15 29 7 30 3 31 1 
這就很明顯了 s>>>=i; 此時s是byte型別>>>1到24的值(int)都超過byte的取值範圍了.btw 如果是short型別 s>>>i在i=17時開始17 32767 18 16383 19 8191 20 4095 21 2047 22 1023 23 511 24 255 25 127 26 63 27 31 28 15 29 7 30 3 31 1 

s=(short)(s>>>10);//就醬

怪不得網上沒找到解答,原來這麼簡單新手在此記錄下!