title: 按位邏輯操作符那些事兒
date: 2017-02-24
tag: java
按位操作符運算符概述
在java底層裡面,用到了很多這種符号,不對這些按位邏輯符号弄清楚,不容易看懂jdk源碼,這裡對按位符号做一個簡單的梳理
運算符 | 用法 | 描述 |
---|---|---|
按位與( AND) | | 對于每一個比特位,隻有兩個操作數相應的比特位都是1時,結果才為1,否則為0。 |
按位或(OR) | | 對于每一個比特位,當兩個操作數相應的比特位至少有一個1時,結果為1,否則為0。 |
按位異或(XOR) | | 對于每一個比特位,當兩個操作數相應的比特位有且隻有一個1時,結果為1,否則為0。 |
按位非(NOT) | | 反轉操作數的比特位,即0變成1,1變成0。 |
左移(L) | | 将 的二進制形式向左移 (< 32) 比特位,右邊用0填充。 |
有符号右移 | | 将 a 的二進制表示向右移 (< 32) 位,丢棄被移出的位。 |
無符号右移 | | 将 a 的二進制表示向右移 (< 32) 位,丢棄被移出的位,并使用 0 在左側填充。 |
這裡注意,java裡面沒有無符号左移,因為無符号左移<<<和左移<<是一樣的概念
按位邏輯操作符
& (按位與)
對每對比特位執行與(AND)操作。隻有 a 和 b 都是 1 時,a AND b 才是 1。與操作的真值表如下:
a | b | a AND b |
---|---|---|
1 | ||
1 | ||
1 | 1 | 1 |
上代碼:
@Test
public void testAnweiyu(){
//按位與,1與0位0,1與1為1,0與0為0
int a= & ;
toBinaryOutPut(,"&",);
System.out.println(Integer.toBinaryString(a)+"===="+a);
}
結果:
&
====
| (按位或)
對每一對比特位執行或(OR)操作。如果 a 或 b 為 1,則
a
OR
b
結果為 1。或操作的真值表:
a | b | a OR b |
---|---|---|
1 | 1 | |
1 | 1 | |
1 | 1 | 1 |
@Test
public void testAnweiHuo(){
//按位或,1或0為1,0或0為0,1或1為1
int a= | ;
toBinaryOutPut(,"|",);
System.out.println(Integer.toBinaryString(a)+"===="+a);
}
結果
|
====
^ (按位異或)
對每一對比特位執行異或(XOR)操作。當 a 和 b 不相同時,
a
XOR
b
的結果為 1。異或操作真值表:
a | b | a XOR b |
---|---|---|
1 | 1 | |
1 | 1 | |
1 | 1 |
@Test
public void testAnweiYiHuo(){
int a= ^ ;
toBinaryOutPut(,"^",);
System.out.println(Integer.toBinaryString(a)+"===="+a);
}
結果
^
====
~ (按位非)
對每一個比特位執行非(NOT)操作。NOT
a
結果為 a 的反轉(即反碼)。非操作的真值表:
a | NOT a |
---|---|
1 | |
1 |
@Test
public void testAnweiFei(){
int a=~;
System.out.println(Integer.toBinaryString());
System.out.println(Integer.toBinaryString(a)+"===="+a);
}
結果
====-
按位移動操作符
<<有符号左移
該操作符會将第一個操作數向左移動指定的位數。向左被移出的位被丢棄,右側用 0 補充
在數字 x 上左移 y 比特得到 x * 2y
上代碼
@Test
public void testLeftMove(){
int a=<<;//9左移動2位
toBinaryOutPut(,"<<",);
System.out.println(Integer.toBinaryString(a)+"===="+a);
}
結果:
<<
====
>>有符号右移
該操作符會将第一個操作數向右移動指定的位數。向右被移出的位被丢棄,拷貝最左側的位以填充左側。由于新的最左側的位總是和以前相同,符号位沒有被改變。是以被稱作“符号傳播”。
例如,
9 >> 2
得到 2
@Test
public void testRightMove(){
int a=>>;//9右邊移動2位
toBinaryOutPut(,">>",);
System.out.println(Integer.toBinaryString(a)+"===="+a);
}
結果:
>>
====
>>>無符号右移
該操作符會将第一個操作數向右移動指定的位數。向右被移出的位被丢棄,左側用0填充。因為符号位變成了 0,是以結果總是非負的。(譯注:即便右移 0 個比特,結果也是非負的。)
對于非負數,有符号右移和無符号右移總是傳回相同的結果。例如,
9 >>> 2
得到 2 和
9 >> 2
相同
但是對于負數卻不盡相同。
-9 >>> 2
産生 1073741821 這和
-9 >> 2
不同:
上代碼:
@Test
public void testNoSignRightMove(){
int a=->>>;//9無符号右移動2位
toBinaryOutPut(-,">>>",);
System.out.println(Integer.toBinaryString(a)+"===="+a);
}
結果:
>>>
====
提問時間如下:
- 首先負數的二進制為什麼是這樣的?
在計算機中,負數以其正值的補碼形式表達,将二進制數按位取反,所得的新二進制數稱為原二進制數的反碼,然後反碼+1就是補碼了
例如:9的原碼是00000000 00000000 00000000 00001001
反碼是11111111 11111111 11111111 11110110
補碼是11111111 11111111 11111111 11110111
是以-9是這樣的
- int在計算機中存儲的是4位元組,是以有32位,是以這麼長,前面正數是因為把前面的0省略了
- 那麼有符号右移和無符号右移有什麼差別呢?
一個是copy最左側的位來填充,一個是用0來填充,是以無符号右移總是一個正數