Java的位運算 符詳解
運算符:運算符是一種特殊的符号,用以表示資料的運算、指派和比較等。
- Java有六種運算符,分别是:
算術運算符 指派運算符 比較運算符(關系運算符) 邏輯運算符 位運算符 三元運算符
其中位運算符效率最高,因為電腦執行的是機器語言,也就是有“0”和“1”組成的二進制數,而位運算是對機器碼二進制直接進行操作 。
這裡我隻和大家分享java的7種 位運算符 。不對的地方請大家多多包涵。
注:在計算機在存儲資料時,存儲的是資料的二進制補碼
1、與運算符
與運算符用符号 “&” 表示,其使用規律是:
隻有兩個操作數的二進制位都為1,結果才為1,否則結果為0。
// 正數 與運算
public class WeiYunSuan {
public static void main(String[] args) {
int a = 2;
int b = 3;
System.out.println("a和b 與運算的結果:"+(a & b));
}
}
運作結果:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZwpmLzcjMyMDMwETM3ATMxkTMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
下面進行分析:(因為 int 是4個位元組,32位,這裡我隻列出 8 位,正數符号位是0)
“a”的值是 2,轉換成二進制就是0000 0010
“b”的值是 3,轉換成二進制就是0000 0011
結果 0000 0010 即:2。
因為正數的 原碼 和 補碼 一樣,是以運算時可直接進行操作。
接下來我們讓兩負數進行運算:
//負數 與運算
public class WeiYunSuan {
public static void main(String[] args) {
int a = -2;
int b = -3;
System.out.println("a和b 與運算的結果:"+(a & b));
}
}
運算結果為:
下面進行分析:(負數的符号位是 1,且負數的原碼、反碼、補碼不一緻)
“a”的值是 -2,轉換成二進制就是:1000 0000 0000 0000 0000 0000 0000 0010
反碼:1111 1111 1111 1111 1111 1111 1111 1101
補碼:1111 1111 1111 1111 1111 1111 1111 1110
“b”的值是 -3,轉換成二進制就是:1000 0000 0000 0000 0000 0000 0000 0011
反碼:1111 1111 1111 1111 1111 1111 1111 1100
補碼:1111 1111 1111 1111 1111 1111 1111 1101
在與運算時,要對補碼進行操作,且符号位也要進行運算,結果:
1111 1111 1111 1111 1111 1111 1111 1100
算下來的結果是補碼,其反碼:1111 1111 1111 1111 1111 1111 1111 1011
原碼:1000 0000 0000 0000 0000 0000 0000 0100 即:-4
因為計算機在存儲資料時,是對資料的二進制的補碼進行存儲,是以在進行與運算時,我們要對資料的二進制補碼進行操作,算下來的結果也是補碼,是以我們要對運算結果進行 轉反碼(-1),在進行取反操作(符号位不變)。最後得出的結果就是控制台輸出的結果了。
最後我們讓兩個一正一負進行運算
//一正一負
public class WeiYunSuan {
public static void main(String[] args) {
int a = 1;
int b = -2;
System.out.println("a和b 與運算的結果:"+(a & b));
}
}
運算結果為:
下面進行分析:
“a”的值是 1,轉換成二進制就是:0000 0000 0000 0000 0000 0000 0000 0001
“b”的值是 -2,轉換成二進制就是:1000 0000 0000 0000 0000 0000 0000 0010
反碼:1111 1111 1111 1111 1111 1111 1111 1101
補碼:1111 1111 1111 1111 1111 1111 1111 1110
在與運算時,要對補碼進行操作,且符号位也要進行運算,結果:
0000 0000 0000 0000 0000 0000 0000 0000 即:0
從運算的二進制補碼中可以看出:正數的原碼和補碼一樣,且最高位符号位為0。是以正數在與負數進行與運算時,最後結果永遠是 0 或者 正數。
2、或運算符
或運算符用符号 “|” 表示,其運算規律是:
隻有兩個操作數的二進制位都為0,那麼結果才是0,否則就為1。
其運算的操作數轉換和上述的與運算符道理一緻,隻是運算規律不一樣。
這裡我要強調的是,兩個一正一負的數進行或運算(與運算的差別)
public class WeiYunSuan {
public static void main(String[] args) {
int a = 5;
int b = -6;
System.out.println(a+"和"+b +"或運算的結果:"+(a ^ b)));
}
}
運算結果:
下面進行分析:
“a”的值是 5,轉換成二進制就是:0000 0000 0000 0000 0000 0000 0000 0101
“b”的值是 -6,轉換成二進制就是:1000 0000 0000 0000 0000 0000 0000 0110
反碼:1111 1111 1111 1111 1111 1111 1111 1001
補碼:1111 1111 1111 1111 1111 1111 1111 1010
在或運算時,要對補碼進行操作,且符号位也要進行運算,結果:
1111 1111 1111 1111 1111 1111 1111 1111
反碼:1111 1111 1111 1111 1111 1111 1111 1110
原碼:1000 0000 0000 0000 0000 0000 0000 0001 即:-1
是以,一正一負的兩個數進行或運算,得出的結果永遠是負數。和與運算相反。
3、異或運算符
異或運算符是用符号 “^” 表示的,其運算規律是:
兩個操作數的二進制位中,相同則結果為0,如:1^1=0,0^0=0
不同則結果為1。如:1^0=1
具體運算過程和上述的步驟一樣,大家在運算時隻需注意異或的運算規律。這裡我隻列出代碼:
// 兩正數運算
public class WeiYunSuan {
public static void main(String[] args) {
int a = 8;
int b = 5;
System.out.println(a+"和"+b +"異或運算的結果:"+(a ^ b));
}
}
運算結果為:
// 兩負數
public class WeiYunSuan {
public static void main(String[] args) {
int a = -8;
int b = -5;
System.out.println(a+"和"+b +"異或運算的結果:"+(a ^ b));
}
}
運算結果:
// 一正一負
public class WeiYunSuan {
public static void main(String[] args) {
int a = 5;
int b = -8;
System.out.println(a+"和"+b +"異或運算的結果:"+(a ^ b));
}
}
運算結果:
異或運算大家會發現:
兩正數運算和兩負數運算,結果肯定是 0 或者 正數。兩一正一負進行運算,結果一定是負數。
4、取反運算符
取反運算符用符号 “~” 表示,其運算規律是:
正數取反:各二進制碼按補碼每個位進行取反
負數取反:各二進制碼按補碼每個位進行取反
代碼示範:
public class WeiYunSuan {
public static void main(String[] args) {
int a = 6;
System.out.println(a +"取反運算的結果:"+ ~a );
}
}
運算結果:
下面進行分析:
“a”的值是 6,轉換成二進制就是:0000 0000 0000 0000 0000 0000 0000 0110
補碼和原碼一樣,按位進行取反: 1111 1111 1111 1111 1111 1111 1111 1001
反碼: 1111 1111 1111 1111 1111 1111 1111 1000
原碼: 1000 0000 0000 0000 0000 0000 0000 0111 即:-7
5、左移運算符
左移運算符用符号 “<<” 表示,其運算規律是:
a << 2 表示 a 的二進制碼往左移兩位。
不管是正數還是負數,從高位往左移,空缺位補 0 ,高位丢棄(符号位也丢棄)。
代碼示範:
public class WeiYunSuan {
public static void main(String[] args) {
int a = 6;
System.out.println(a +"左移29位運算的結果:"+ (a<<29) );
}
}
運算結果:
下面進行分析:
“a”的值是 6,轉換成二進制就是:0000 0000 0000 0000 0000 0000 0000 0110
往左移29位,變為:1100 0000 0000 0000 0000 0000 0000 0000
反碼: 1011 1111 1111 1111 1111 1111 1111 1111
原碼: 1100 0000 0000 0000 0000 0000 0000 0000 即:-2^30
6、右移運算符
右移運算符用符号 “>>” 表示,其運算規律是:
右移的話,低位舍去,空缺位根據操作數的最高位(即:符号位)進行補位。
最高位是 0,則補 0;最高位是 1,則補 1。
代碼示範:
public class WeiYunSuan {
public static void main(String[] args) {
int a = -6;
System.out.println(a +"右移1位運算的結果:"+ (a>>1) );
}
}
運算結果:
下面進行分析:
“a”的值是 -6,轉換成二進制就是:1000 0000 0000 0000 0000 0000 0000 0110
反碼:1111 1111 1111 1111 1111 1111 1111 1001
補碼:1111 1111 1111 1111 1111 1111 1111 1010
右移 1 位,為:1111 1111 1111 1111 1111 1111 1111 1101
反碼: 1111 1111 1111 1111 1111 1111 1111 1100
原碼: 1000 0000 0000 0000 0000 0000 0000 0011 即:-3
7、無符号右移
無符号右移運算符的符号用 “>>>” 表示,其運算規律是:
顧名思義:就是被移位的二進制數,最高位不管是 0 還是 1,空缺位都補 0。
代碼示範:
public class WeiYunSuan {
public static void main(String[] args) {
int a = -6;
System.out.println(a +"無符号右移29位運算的結果:"+ (a>>>29) );
}
}
運算結果:
下面進行分析:
“a”的值是 -6,轉換成二進制就是:1000 0000 0000 0000 0000 0000 0000 0110
反碼:1111 1111 1111 1111 1111 1111 1111 1001
補碼:1111 1111 1111 1111 1111 1111 1111 1010
無符号右移 29 位,為:0000 0000 0000 0000 0000 0000 0000 0111 即:7
總結
最後一個問題: 2 在左移運算時的規律,大家想想是什麼?
以上七種位運算符的運算,便是我在學習過程中的了解。其實,隻要記住:電腦在進行運算時使用機器語言進行運算,也就是用二進制的補碼進行存儲運算。是以大家在做這方面的題目時要注意負數的原碼反碼和補碼。