以下是java位操作符的小總結,具體如下
二進位負數以它正值的補碼形式表達
補碼:反碼+1等於補碼
比如:System.out.println(Integer.toBinaryString(-5));
列印:1111 1111 1111 1111 1111 1111 1111 1011 不用想了肯定是32位
過程是這樣的
一個負數,比如-5,它的二進位在java裡面是這樣表示
1000 0000 0000 0000 0000 0000 0000 0101
它的正值是
0000 0000 0000 0000 0000 0000 0000 0101
反碼是
1111 1111 1111 1111 1111 1111 1111 1010
再加上1是
1111 1111 1111 1111 1111 1111 1111 1011
即得到列印的內容
java ~ 操作符,對每個二進位位的內容求反,即1變成0,0變成1
測試負數
int a = -5;//101;
System.out.println(~a);
列印:4
過程是這樣的,首先表示出來這個負數
1111 1111 1111 1111 1111 1111 1111 1011(上面已經提到為什麼這樣表示)
各位取反得到
0000 0000 0000 0000 0000 0000 0000 0100
轉為10進位得到4
測試正數:
int a = 5;//101;
System.out.println(~a);
列印:-6
首先表示出來這個正數
0000 0000 0000 0000 0000 0000 0000 0101
各位取反得到
1111 1111 1111 1111 1111 1111 1111 1010
這個代表的就是-6了,至於為什麼看最上面
java & 操作符,對應的二進位位進行與操作,兩個都為1才為1,其他情況均為0
測試
System.out.println(5&6);
列印:4
過程
5表示成:0000 0000 0000 0000 0000 0000 0000 0101
6表示成:0000 0000 0000 0000 0000 0000 0000 0110
進行 & :0000 0000 0000 0000 0000 0000 0000 0100
得到:4
java | 操作符,對應的二進位位進行或操作,兩個都為0才為0,其他情況均為1
測試
System.out.println(5|6);
列印:7
過程
5表示成:0000 0000 0000 0000 0000 0000 0000 0101
6表示成:0000 0000 0000 0000 0000 0000 0000 0110
進行 | :0000 0000 0000 0000 0000 0000 0000 0111
得到:7
java ^ 操作符 當對應二進位位值相同,該位為0 否則為1
測試
System.out.println(5^6);
列印:3
過程
5表示成:0000 0000 0000 0000 0000 0000 0000 0101
6表示成:0000 0000 0000 0000 0000 0000 0000 0110
進行 ^ :0000 0000 0000 0000 0000 0000 0000 0011
得到:3
java << 操作符,左邊移動,右面填充0
測試
System.out.println(5<<1);
列印:10
5表示成:0000 0000 0000 0000 0000 0000 0000 0101
進行 <<1 操作:0000 0000 0000 0000 0000 0000 0000 1010
java >> 操作符,左邊移動,右面填充0
測試
System.out.println(5>>>1);
列印:2
5表示成:0000 0000 0000 0000 0000 0000 0000 0101
進行 >>>1 操作:0000 0000 0000 0000 0000 0000 0000 0010
左移動一位相當乘以2 右移動一位相當處以2
負數的帶符號和不帶符號的右移運算
package c03;public class URShift {public static void main(String[] args) {int i = -1;i >>>= 10;System.out.println(i);}}
package c03;public class URShift {public static void main(String[] args) {int i = -1;i >>>= 10;System.out.println(i);}}
其結果為:4194303
怎麼來的呢?
因為java裡的int型是32位的,且負數的儲存以補碼(符號位保持不變,其他位是儲存數的絕對值按位取反加1)方式:故而-1在儲存空間的存放為:
其值為2^32-1=4294967255;
故而無符號右移10位:變成如所示:
其值為2^22-1=4194303;
對於帶符號右移,若為負數,則在儲存時首位表示符號位,其值為1,表示該值是負數的移位,在移位過程中,高位補1,若符號位是0,表示是正數,在移位過程中高位補零,兩者的前提是符號位保持不變:
package c03;public class URShift {public static void main(String[] args) {int i = -1, j = 10000;i >>= 10;j >>= 10;System.out.println(i + ", " + j);}}
package c03;public class URShift {public static void main(String[] args) {int i = -1, j = 10000;i >>= 10;j >>= 10;System.out.println(i + ", " + j);}}
輸出為:-1, 9
拿-1為例,因為右移,高位補1,所以-1的右移始終不變.
然後求補碼加1;
| 1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
再例,-100帶符號右移四位,其值為-7:
原碼為:
| 1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
0 |
1 |
0 |
0 |
補碼為:
| 1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
0 |
0 |
右移四位後:
| 1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
1 |
0 |
0 |
1 |
保留符號位,按位取反:
| 1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
0 |
再加1,即得原碼:
| 1 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
0 |
1 |
1 |
1 |