【Java】位操作符

Nemo&發表於2021-02-08

位運算子

java支援的位運算子有7個,分為兩類:位邏輯運算和移位運算。位邏輯運算子包括按位取反(~)、按位與(&)、按位或(|)和按位異或(^)4種,。移位運算子包括左移(<<)、右移(>>)和無符號右移(>>>)3種。位運算子只能用於整型資料,包括byte、short、int、long和char型別。下表列出了各種位運算子的功能與示例。假設a = 10, b = 3。

~運算子是對運算數的每一位按位取反。

下表列出了位運算子的基本運算,假設整數變數A的值為60和變數B的值為13:

操作符 描述 例子
& 如果相對應位都是1,則結果為1,否則為0 A & B得到12,即0000 1100
| 如果相對應位都是0,則結果為0,否則為1 A | B得到61,即 0011 1101
^ 如果相對應位值相同,則結果為0,否則為1 A ^ B得到49,即 0011 0001
~ 按位取反運算子翻轉運算元的每一位,即0變成1,1變成0。 ~A得到-61,即1100 0011
<< 按位左移運算子。左運算元按位左移右運算元指定的位數。
(低位補零)
A << 2得到240,即 1111 0000
>> “有符號”按位右移運算子。左運算元按位右移右運算元指定的位數。
該操作符使用 “符號擴充套件”:若符號為正,則高位插入 0;若符號為負,則高位插入 1。
A >> 2得到15即 1111
>>> “無符號”按位右移補零操作符。左運算元的值按右運算元指定的位數右移,移動得到的空位以零填充。
該操作符使用 “零擴充套件”,無論正負,都在高位插入 0。
A>>>2得到15即0000 1111

按位操作符

按位操作符用來操作整數的二進位制位,會對兩個引數中對應的位執行布林代數運算,並最終生成一個結果。

與操作符 “&”,如果兩個輸入位都是 1,那麼輸出位是 1,否則輸入位是 0;
或操作符 “|” ,如果兩個輸入位有一個是 1,那麼輸出位是 1,只有兩個輸入位都是 0,輸出位才是 0;
異或運算子 “^”,如果兩個輸入位都為 1 或者都為 0,那麼輸出位是 0,否則輸出位是 1。
非運算子 “~”,這個一元操作符,只能對一個數操作,規則是輸出位與輸入位相反。

//轉化為二進位制:0101
int num1 = 5;
//轉化為二進位制:1001
int num2 = 9;
//與運算,二進位制結果為 0001,列印結果為 1
System.out.println(num1 & num2);
//或運算,二進位制結果為 1101,列印結果為 13
System.out.println(num1 | num2);
//異或運算,二進位制結果為 1100,列印結果為 12
System.out.println(num1 ^ num2);
//非運算,二進位制結果為 11111111111111111111111111111010,列印結果 -6
System.out.println(Integer.toBinaryString(~num1));

好吧,進哥承認,我看到那個 -6 也蒙了那麼一下,所以整理了以下內容。

補充

數字的二進位制表現形式為 “有符號的二進位制補碼”。
原碼:數字的二進位制表示法,最高位為符號位, “ 0 ” 為正,“ 1 ” 為負。
反碼:正數的反碼與原碼相同,負數的反碼對原碼逐位取反,符號位除外。
補碼:正數的補碼與原碼相同,負數的補碼在其反碼末位加 1。
負數的二進位制演算法(以 -6 為例):
1)將 -6 的絕對值轉化為二進位制,即:00000000 00000000 00000000 00000110
2)求該二進位制數的反碼,即:11111111 11111111 11111111 11111001
3)對以上求得的二進位制數加 1,即:11111111 11111111 11111111 11111010

移位操作符

移位操作符的運算物件也是二進位制的 “位”,但是隻能用來處理整數型別。

  • 左移位操作符 “<<” 按照操作符右側指定的位數將操作符左邊的運算元向左移動(低位補零);

  • “有符號”右移位操作符 “>>” 按照操作符右側指定的位數將操作符左邊的運算元向右移動。該操作符使用 “符號擴充套件”:若符號為正,則高位插入 0;若符號為負,則高位插入 1。

  • “無符號”右移位操作符 “>>>”,該操作符使用 “零擴充套件”,無論正負,都在高位插入 0。

//二進位制 1111;
int i = 15;
//向右邊移動兩位,二進位制結果為 0011,列印結果為 3
System.out.println(i >> 2);
//向左邊移動兩位,二進位制結果為 111100,列印結果為 60
System.out.println(i << 2);

移位操作符可以與等號組合使用(<<= 或 >>= 或 >>>=),表示操作符左邊的值會移動由右邊數值指定的位數,再將得到的結果賦給左邊的變數。


Java運算子

Java運算子按功能可分為:算數運算子、關係運算子、邏輯運算子、位運算子、賦值運算子和條件運算子。

算數運算子

算術運算子包括通常的加(+)、減(-)、乘(*)、除(/)、取模(%),完成整數型和浮點型資料的算術運算。

許多語言中的取模運算只能用於整數型,Java對此做了擴充套件,它允許對浮點數進行取模操作。例如,3%2 的結果是 1, 15.2%5 的結果是 0.2。取模操作還可以用於負數,結果的符號與第一個運算元的符號相同,例如,5%-3 的結果是 2,-5%3 的結果是-2。

此外,算術運算子還有“++”和“--”兩種,分別稱為加1和減1運算子。這兩種運算子有字首形式和字尾形式,含有有所不同。例如,i++ 和 ++i 的執行順序是不一樣的,i++ 在 i 使用之後再 +1,++i 在 i 使用之前先 +1。i-- 和 --i 的情況於此類似。

例子:

int i = 1;
System.out.println(i++); //i++,使用之後+1,此處輸出1

int i = 1;
System.out.println(++i); //++i,先+1再使用,此處輸出2

int i = 1;
System.out.println(i--); //i--,使用之後-1,此處輸出1

int i = 1;
System.out.println(--i); //--i,先-1再使用,此處輸出0

關係運算子

關係運算子用來比較兩個值,包括大於(>)、小於(<)、大於等於(>=)、小於等於(<=)、等於(==)和不等於(!=)6種。關係運算子都是二元運算子,也就是每個運算子都帶有兩個運算元,運算的結果是一個邏輯值。Java允許“==”和“!=”兩種運算子用於任何資料型別。例如,既可以判斷兩個數的值是否相等,也可以判斷物件或陣列的例項是否相等。判斷例項時比較的是兩個物件在記憶體中的引用地址是否相等。

邏輯運算子

邏輯運算子包括邏輯與(&&)、邏輯或(||)和邏輯非(!)。前兩個是二元運算子,後一個是一元運算子。Java對邏輯與和邏輯或提供“短路”功能,也就是在進行運算時,先計算運算子左側的表示式的值,如果使用該值能得到整個表示式的值,則跳過運算子右側表示式的計算,否則計算運算子右側表示式,並得到整個表示式的值。

//邏輯與&&,有一個表示式的結果是false,整體就返回false
String str = null;
if(str != null && str.length0 > 2) {
      // str是null, &&左側的表示式的結果是false,不會計算&&右側的表示式,直接整體返回false
}

str= "abc";
if(str != null && str.length0> 5) {
      // &&左側的表示式的結果是true,會接著計算&&右側的表示式,右側表示式的值是false,整個if中的表示式的結果就返回false
}

//邏輯或||,有一個表示式的結果是true,整體就返回true
str= "qq";
if(str == null II str.length0== 2) {
      // ||左側的表示式的結果是false,會接著計算||右側的表示式,右側結果是true, 則整體返回true
}
if(str != null II str.ength0 == 2) {
      // ||左側的表示式的結果是true, 不會計算||右側的表示式, 直接整體返回true
}

//邏輯非!,表示式結果是true,就返回false; 表示式結果是false,就返回true
boolean flag = true;
System.out.printIn(!flag); //輸出false
flag = false;
System.out.printn(!flag); //輸出true

位運算子

位運算子用來對二進位制位進行操作,包括按位取反(~)、按位與(&)、按位或(|)、異或(^)、右移(>>)、左移(<<)和無符號右移(>>>)。位運算子只能對整數型和字元型資料進行操作。

1. 取反(~)

參加運算的一個資料,按二進位制位進行“取反”運算。

運算規則:~1=0; ~0=1;

即:對一個二進位制數按位取反,即將0變1,1變0。

2. 按位與(&)

參加運算的兩個資料,按二進位制位進行“與”運算。

運算規則:0&0=0; 0&1=0; 1&0=0; 1&1=1;即:兩位同時為“1,結果才為“1,否則為0。

例如:3&5 即 0000 0011 & 0000 0101 = 0000 0001 因此,3 & 5的值得1。

3. 按位或(|)

參加運算的兩個物件,按二進位制位進行“或”運算。

運算規則:0 | 0=0; 0 | 1=1; 1 | 0=1; 1 | 1=1;

即 :參加運算的兩個物件只要有一個為1,其值為1。

例如:3 | 5,即 0000 0011 | 0000 0101 = 0000 0111 因此,3 | 5的值得7。

4. 異或(^)

參加運算的兩個資料,按二進位制位進行“異或”運算。

運算規則:0^0=0; 0^1=1; 1^0=1; 1^1=0;

即:參加運算的兩個物件,如果兩個相應位為“異”(值不同),則該位結果為1,否則為0。

5. 左移(<<)

運算規則:按二進位制形式把所有的數字向左移動對應的位數,高位移出(捨棄),低位的空位補零。例如: 12345 << 1,則是將數字12345左移1位:
【Java】位操作符

位移後十進位制數值變成:24690,剛好是12345的二倍,所以有些人會用左位移運算子代替乘2的操作,但是這並不代表是真的就是乘以2,很多時候,我們可以這樣使用,但是一定要知道,位移運算子很多時候可以代替乘2操作,但是這個並不代表兩者是一樣的。

思考一下:如果任意一個十進位制的數左位移32位,右邊補位32個0,十進位制豈不是都是0了?當然不是!!! 當int 型別的資料進行左移的時候,當左移的位數大於等於32位的時候,位數會先求餘數,然後再進行左移,也就是說,如果真的左移32位 12345 << 32 的時候,會先進行位數求餘數,即為 12345<<(32%32) 相當於 12345<< 0 ,所以12345<< 33 的值和12345<<1 是一樣的,都是 24690。

6. 右移(>>)

同樣,還是以12345這個數值為例,12345右移1位: 12345>>1。
【Java】位操作符

右移後得到的值為 6172 和int 型別的資料12345除以2取整所得的值一樣,所以有些時候也會被用來替代除2操作。另外,對於超過32位的位移,和左移運算子一樣,,會先進行位數求餘數。

7. 無符號右移(>>>)

無符號右移運算子和右移運算子是一樣的,不過無符號右移運算子在右移的時候是補0的,而右移運算子是補符號位的。以下是-12345二進位制表示:
【Java】位操作符

對於原始碼、反碼、補碼不熟悉的同學,請自行學習,這裡就不再進行補充了講解了,這裡提醒一下,在右移運算子中,右移後補0,是由於正數 12345 符號位為0 ,如果為1,則應補1。
【Java】位操作符

1、原碼、反碼和補碼說明:一個數可以分成符號位(0正1負)+ 真值,原碼是我們正常想法寫出來的二進位制。由於計算機只能做加法,負數用單純的二進位制原碼書寫會出錯,於是大家發明了反碼(正數不變,負數符號位不變,真值部分取反);再後來由於+0, -0的爭端,於是改進反碼,變成補碼(正數不變,負數符號位不變,真值部分取反,然後+1)。二進位制前面的0都可以省略,所以總結來說:計算機裡的負數都是用補碼(符號位1,真值部分取反+1)表示的。2、位運算子和2的關係位運算子和乘2、除2在大多數時候是很相似的,可以進行替代,同時效率也會高的多,但是兩者切記不能混淆 ;很多時候有人會把兩者的概念混淆,尤其是資料剛好是 2、4、6、8、100等偶數的時候,看起來就更相似了,但是對於奇數,如本文使用的12345 ,右移之後結果為6172 ,這個結果就和數學意義上的除以2不同了,不過對於int 型別的資料,除2 會對結果進行取整,所以結果也是6172 ,這就更有迷惑性了。

賦值運算子

賦值運算子的作用就是將常量、變數或表示式的值賦給某一個變數。

運算子 運算 範例 結果
= 賦值 a=3;b=2; a=3;b=2;
+= 加等於 a=3;b=2;a+=b; a=5;b=2;
-= 減等於 a=3;b=2;a-=b; a=1;b=2;
*= 乘等於 a=3;b=2;a*=b; a=6;b=2;
/= 除等於 a=3;b=2;a/=b; a=1;b=2;
%= 模等於 a=3;b=2;a%=b; a=3;b=2;

除了“=”,其它的都是特殊的賦值運算子,以“+=”為例,x += 3就相當於x = x + 3,首先會進行加法運算x+3,再將運算結果賦值給變數x。-=、*=、/=、%=賦值運算子都可依此類推。

條件運算子

條件運算子( ? : )也稱為 “三元運算子”或“三目運算子”。

語法形式:布林表示式 ? 表示式1 :表示式2。

運算過程:如果布林表示式的值為 true ,則返回 表示式1的值,否則返回 表示式2 的值。

運算子的優先次序

在對一個表示式進行計算時,如果表示式中含有多種運算子,則要安運算子的優先次序一次從高向低進行。運算子的優先次序如下:

【Java】位操作符

優先順序 運算子 簡介 結合性
1 []、.、() 方法呼叫,屬性獲取 從左向右
2 !、~、++、-- 一元運算子 從右向左
3 *、/、% 乘、除、取模(餘數) 從左向右
4 +、- 加、減 從左向右
5 <<、>>、>>> 左位移、右位移、無符號右位移 從左向右
6 <、<=、>、>=、instanceof 小於、小於等於、大於、大於等於
物件型別判斷是否屬於同型別
從左向右
7 ==、!= 相等、不相等 從左向右
8 & 按位與 從左向右
9 ^ 按位異或 從左向右
10 | 按位或 從左向右
11 && 邏輯與 從左向右
12 || 邏輯或 從左向右
13 ? 條件運算子 從右向左
14 =、+=、-=、*=、/=、%=、&=、|=、^=、>>= 混合賦值運算子 從右向左

相關文章