Java中的位運算

jimmie_yang發表於2018-08-21

預備知識

原碼 : 符號位加上真值的絕對值, 即用第一位表示符號, 其餘位表示值。

反碼 : 正數的反碼是其本身;負數的反碼是在其原碼的基礎上, 符號位不變,其餘各個位取反。

補碼 :
在計算機中,二進位制數值是以補碼的形式存放, 正數補碼是其本身,負數的補碼為 除符號位的(反碼+1)

計算機中的數值是以其補碼的方式儲存的.

java中的基礎位運算子

java中提供的基礎位運算子有 與(&),或(|),非(~),異或(^),左移<<,
右移(>>)無符號右移(>>>).

除了位非(~)是一元操作符外,其它的都是二元操作符。

以下的 A,B為二進位制表示的數字.

按位與

A & B : A和B對應的二進位制數位都為1時,結果才為1,其他情況為0.

A     =  001101 // 13
B     =  100101 // 37
A & B =  000101 // 5

按位或

A | B : A和B對應的二進位制數位都為0時,結果才為0,其他情況為1.

A     =  001101 // 13
B     =  100101 // 37
A | B =  101101 // 45

按位非

~A : 將a的二進位制表示每一位進行取反操作,0變1,1變0.
相當於相反數 – 1

A     =  001101 // 13
~A    =  11111111111111111111111111110010 // 32位,補碼錶示,第一位為符號位
// 根據上訴補碼轉原碼為
//       10000000000000000000000000001110 // -14

按位異或

A ^ B:將A和B對應的二進位制位不同,結果位為1,否則為0。

A     =  001101 // 13
B     =  100101 // 37
A | B =  101000 // 40

左移操作

A << B:將A的二進位制表示的每一位向左移B位,左邊超出的位截掉,右邊不足的位補0。
在取值範圍內,移動一位相當於乘2.

A     =  001101 // 13
A << 1 = 011010 // 26

右移操作

A >> B: 是帶符號右移,若左運算元是正數,則高位補“0”,若左運算元是負數,則高位補“1”.
在取值範圍內,移動一位相當於除2.

A     =  001101 // 13
A >> 1 = 000110 // 6

無符號右移操作

A >>> B: 是無符號右移,無論左運算元是正數還是負數,在高位都補“0”
在取值範圍內,正數移動一位相當於除2.

A       = 11111111111111111111111111110011 // -13
A >>> 1 = 01111111111111111111111111111001 // 2147483641

位運算例子

  1. 根據 A ^ A = 0的特性,完成數值交換
int a = 2;
int b = 3;
a = a ^ b;
b = a ^ b;
a = a ^ b;
System.out.println(a); // 3
System.out.println(b); // 2
  1. 整型字元的 乘 2 ^ n 或者 除 2 ^ n
A     =  001101 // 13
A >> 1 = 000110 // 相當於 13 / 2 
  1. 判斷一個數的奇偶性

最後二進位制最後一位是1為奇數,為0是偶數.

    boolean isOddNumber(int n){
        return (n & 1) == 1;
    }
  1. A ^ -1 相當 ~A.

  2. 求相反數

    int oppositeNumber(int num) {
        return ~num + 1;
    }
  1. 求絕對值
    /**
     * n>>31 取決於n的符號,若n為正數,n>>31等於0,若n為負數,n>>31等於-1
     * 負數時,相當於 (n ^ -1) + 1
     */
    int abs(int n) {
        return (n ^ (n >> 31)) - (n >> 31);
    }
  1. 求最大值
    /**
     * b & -1 == b
     * ~0  == -1
     */
    int max(int a, int b) {
        return b & ((a - b) >> 31) | a & (~(a - b) >> 31);
    }
  1. 求最小值
    /**
     * b & -1 == b
     * ~0  == -1
     */
    int max(int a, int b) {
        return a & ((a - b) >> 31) | b & (~(a - b) >> 31);
    }
  1. 判斷符號相同
    /**
     * 有 0 時,方法不成立.
     * @return true 表示 x和y有相同的符號, false表示x,y有相反的符號。
     */
    boolean isSameSign(int x, int y) {
        return (x ^ y) >= 0;
    }
  1. 取平均值
    int average(int x, int y) {
        return (x + y) >> 1;
    }


相關文章