java提供的位運算符有:
第一部分: &(位與),|(位或),^(位異或),~(位非)
第二部分: >>(右移),>>>(無符號右移),<<(左移)
其中除~爲一元操作符,其他的都是二元操作符。
根據運算模式不同分爲兩部分
一.第一部分
&,|,^,~ 的運算規則
* &:有0則0
* |:有1則1
* ^:相同則0,不同則1
* ~:按位取反
案例:
class Demo1_Operator {
public static void main(String[] args) {
/*
* &,|,^,~ 的用法
* &:有0則0
* |:有1則1
* ^:相同則0,不同則1
* ~:按位取反
*/
System.out.println(6 & 3); //2
System.out.println(6 | 3); //7
System.out.println(6 ^ 3); //5
System.out.println(~6); //-7
}
}
110
& 011
-----------
010
b. 6 | 3 的二進制位運算過程:有1則1
110
| 011
-------------
111
c. 6 ^ 3 的二進制位運算過程:相同則0,不同則1
110
^ 011
-------------
101
d. 6 ^ 3 的二進制位運算過程:按位取反
00000000 00000000 00000000 00000110 //6的原碼反碼補碼都是本身
11111111 11111111 11111111 11111001 // 對6取反得補碼
- 00000000 00000000 00000000 00000001 //減1求反碼
-----------------------------------------------------------
11111111 11111111 11111111 11111000 //反碼,對反碼進行除符號位以外其他位上按位取反。
10000000 00000000 00000000 00000111 //求得原碼(-7)
位運算之面試題
核心要點:^的特點:一個數據對另一個數據位異或兩次,該數本身不變。
題目:請自己實現兩個整數變量的交換(不需要定義第三方變量)
案例:
class Demo2_Operator {
public static void main(String[] args) {
/*
* 位異或運算符的特點
* ^的特點:一個數據對另一個數據位異或兩次,該數本身不變。
*/
int x = 10;
int y = 5;
//需要第三方變量
/*
int temp;
temp = x; //temp = 10
x = y; //x = 5
y = temp; //y = 10
*/
//不需要定義第三方變量,有弊端,有可能會超出int的取值範圍
/*
x = x + y; //10 + 5 = 15
y = x - y; //15 - 5 = 10
x = x - y; //15 - 10 = 5
*/
//不需要第三方變量,通過^來做
x = x ^ y; // 10 ^ 5
y = x ^ y; // 10 ^ 5 ^ 5 y = 10
x = x ^ y; // 10 ^ 5 ^ 10 x = 5
System.out.println("x = " + x + ",y = " +
y);}
}
>>,>>>,<<的基本運算規則: a 位移運算符 b (a表示要進行位移的數,b表示位移的位數)
1. <<:左移 左邊最高位丟棄,右邊補齊0
2. >>:右移 最高位是0,左邊補齊0;最高位是1,左邊補齊1
3. >>>:無符號右移 無論最高位是0還是1,左邊補齊0(正數適合,負數不適合,負數右移會變成正數)
4. 最有效率的算出2 * 8的結果
案例:
- class Demo3_Operator {
- public static void main(String[] args) {
- /*
- * <<:左移 左邊最高位丟棄,右邊補齊0
- * >>:右移 最高位是0,左邊補齊0;最高爲是1,左邊補齊1
- * >>>:無符號右移 無論最高位是0還是1,左邊補齊0
- * 最有效率的算出2 * 8的結果
- */
- //左移,向左移動幾位就是乘以2的幾次冪
- //System.out.println(12 << 1); //24
- //System.out.println(12 << 2); //48
- /*
- 00000000 00000000 00000000 00001100 12的補碼
- (0)0000000 00000000 00000000 000011000 24的補碼
- (00)000000 00000000 00000000 0000110000 48的補碼
- */
- //System.out.println(-12 << 1); //-24
- //System.out.println(-12 << 2); //-48
- /*
- 10000000 00000000 00000000 00001100 -12的原碼
- 11111111 11111111 11111111 11110011 -12的反碼
- 11111111 11111111 11111111 11110100 -12的補碼
- (1)11111111 11111111 11111111 11101000 -24的補碼
- 11111111 11111111 11111111 11100111 -24的反碼
- 10000000 00000000 00000000 00011000 -24的原碼
- */
- //右移,向右移動幾位就是除以2的幾次冪
- //System.out.println(12 >> 1); //結果爲 6
- //System.out.println(-12 >> 1); //結果爲 -6
- /*
- 00000000 00000000 00000000 00001100 12的補碼
- 00000000 00000000 00000000 00000110 6的補碼
-
-
- 10000000 00000000 00000000 00001100 -12的原碼
- 11111111 11111111 11111111 11110011 -12的反碼
- 11111111 11111111 11111111 11110100 -12的補碼
- 11111111 11111111 11111111 11111010(0) -6的補碼
- 11111111 11111111 11111111 11111001 -6的反碼
- 10000000 00000000 00000000 00000110 -6的原碼
- */
-
- //System.out.println(12 >>> 1); //運算規則與>>一樣 結果爲6,在這裏不做位運算詳解了
- //System.out.println(-12 >>> 1); // 右移,最高位補0 結果2147483644
-
- /*
-
- 10000000 00000000 00000000 00001100 -12的原碼
- 11111111 11111111 11111111 11110011 -12的反碼
- 11111111 11111111 11111111 11110100 -12的補碼
- 01111111 11111111 11111111 11111010(0) 2147483644的補碼
- 01111111 11111111 11111111 11111010 2147483644的原碼
- */
- //最有效率的算出2 * 8的結果 ,位運算的效率是比運算符的效率要高的.
- System.out.println(2 << 3);
-
- }
- }