1. 程式人生 > >java中的無符號移位運算

java中的無符號移位運算

color 位運算 沒有 區分 進制 ger 存在 pri 符號

1. 無符號右移 >>> 或 >>> =

無符號右移(>>>)跟右移(>>)運算符不一樣。

右移不改變數的正負。

對於一個正數,無符號右移不會變成負數(相當於除以1再取整);但是對於一個負數,無符號右移會將負數變成正數;


int i = -4;
System.out.printf("%-10d %32s\n", i, Integer.toBinaryString(i));
i >>>= 1; // 無符號右移1位
System.out.printf("%-10d %32s\n", i, Integer.toBinaryString(i));

i >>>= 1;
System.out.printf("%-10d %32s\n", i, Integer.toBinaryString(i));

輸出:

-4 11111111111111111111111111111100 //負數在java中以補碼形式存儲,-4的補碼表示是11111111111111111111111111111100
2147483646 1111111111111111111111111111110 //無符號右移1位,-4的補碼表示的符號位也右移了1位,導致符號位變成0,成為正數
1073741822 111111111111111111111111111110 //再無符號右移1位

int i = 15;
System.out.printf("%-10d %32s\n", i, Integer.toBinaryString(i));
i >>>= 1;
System.out.printf("%-10d %32s\n", i, Integer.toBinaryString(i));

輸出:

15 1111  
7 111  //對正數進行無符號右移,高位補0

int i = 0x80000000;
System.out.printf("%-12d %32s\n", i, Integer.toBinaryString(i));
i >>>= 1;
System.out.printf(
"%-12d %32s\n", i, Integer.toBinaryString(i)); i >>>= 1; System.out.printf("%-12d %32s\n", i, Integer.toBinaryString(i));

輸出:

-2147483648 10000000000000000000000000000000 //最小負數的補碼表示
1073741824 1000000000000000000000000000000 //符號位右移一位,變成正數
536870912 100000000000000000000000000000

總結:

無符號右移的叫法,容易讓人誤解。雖然叫作無符號右移運算,讓人第一印象以為是不對符號位進行移位,其實卻是連同符號位一起右移;

對復數進行無符號右移,符號位也一起右移,將會變成正數;

對正數進行若幹次無符號右移,得到的永遠都是正數或0;

2. 左移位運算 << 或 <<=

跟右移運算不同的是,無符號左移和左移是一樣的。因此java沒有無符號左移運算。(<<<和<<<=將報錯)

因為無右移運算需要考慮符號位的右移,而符號位只存在於二進制表示的最左邊,最右邊沒有。

所以不用區分無符號左移和左移運算。

int i = 0x80000000;
System.out.printf("%-12d %32s\n", i, Integer.toBinaryString(i));
i <<= 1;
System.out.printf("%-12d %32s\n", i, Integer.toBinaryString(i));
i >>= 1;
System.out.printf("%-12d %32s\n", i, Integer.toBinaryString(i));

輸出:

-2147483648 10000000000000000000000000000000
0 0 //最小負數左移1位,將變成0
0 0

java中的無符號移位運算