Java使用補碼來表示二進制數, 在計算機運算的時候, 都是以補碼的方式來運算。在補碼錶示中,最高位爲符號位,正數的符號位爲0,負數爲1。補碼的規定以下:
· 對正數來講,最高位爲0,其他各位表明數值自己(以二進制表示)。正數的原碼、反碼、補碼都同樣。
· 對負數而言,把該數絕對值的補碼按位取反,而後對整個數加1,即得該數的補碼。如下是-1補碼的計算過程:
函數
10000000000000000000000000000001 (-1的原碼)
11111111111111111111111111111110 (-1的反碼:原碼除符號位按位取反)
11111111111111111111111111111111 (-1的補碼:反碼加1)spa
1、位運算的概念3d
位運算表達式由操做數和位運算符組成,實現對整數類型的二進制數進行位運算。code
位運算符能夠分爲邏輯運算符(包括~、&、|和^)及移位運算符(包括>>、<<和>>>)。對象
&(與):當兩邊操做數的位同時爲1時,結果爲1,不然爲0。 如1100&1010=1000
| (或) :當兩邊操做數的位有一邊爲1時,結果爲1,不然爲0。 如1100|1010=1110
~(非):0變1,1變0。 如 ~1100=0011
^(異或) :兩邊的位不一樣時,結果爲1,不然爲0。 如1100^1010=0110
<<(左移):a向左移動b指定的位數(在低位補0)。表示原來的值乘2。(a<<b, a表示運算符左側的運算對象,b表示右側的數值)
>>(右移):a向右移動b指定的位數。若值爲正,則在高位插入0;若值爲負,則在高位插入1。
>>>(無符號右移):a向右移動b指定的位數。不管正負,都在高位插入0。這一運算符是C或C++沒有的。blog
位運算符的優先級:~的優先級最高,其次是<<、>>和>>>,再次是&,而後是^,優先級最低的是|。hash
public class Test { public static void main(String[] args) { Integer a = Integer.MAX_VALUE; Integer b = Integer.MIN_VALUE; toBinary("(MAX_INT) a", a); toBinary("(MIN_INT) b", b); toBinary("~ b", ~b); toBinary("a & b", a & b); toBinary("a | b", a | b); toBinary("a ^ b", a ^ b); toBinary("b << 2", b << 2); toBinary("b >> 2", b >> 2); toBinary("b >>> 2", b >>> 2); } public static void toBinary(String op, Integer a) { String str = Integer.toBinaryString(a); System.out.printf("%n%11s: ", op); for(int i = 0, delta = 32 - str.length(); i < 32; i++){ if(i < delta) System.out.print("0"); else System.out.print(str.charAt(i - delta)); if((i + 1) % 8 ==0) System.out.print(" "); } } }
運行結果table
2、位運算的應用class
3*2^5 : (3<<5))變量
法則一:任何數左移(右移)32的倍數位等於該數自己。
法則二:在位移運算m<<n的計算中,若n爲正數,則實際移動的位數爲n%32,若n爲負數,則實際移動的位數爲(32+n%32),右移,同理。
n&1 == 1? "奇數" : "偶數"
int類型的1前31位都是0,最低位爲1,當一個數爲奇數,其最低位也是1。
異或沒有順序性,且知足如下規則:
① a ^ a =0
② a ^ b =b ^ a
③ a ^b ^ c = a ^ (b ^ c) = (a ^ b) ^ c;
④ d = a ^b ^ c 能夠推出 a = d ^ b ^ c.
⑤ a ^ b ^a = b.
根據第五個規則,能夠交換變量值。
public class Test { public static void main(String[] args) { int a = 4; int b = 10; a = a ^ b; b = a ^ b; a = a ^ b; System.out.println("a=" + a + ", b=" + b); } }
運行結果: a=10, b=4
計算過程以下:
a = a ^ b
b = a ^ b = (a ^ b) ^ b = a
a = a ^ b = (a ^ b) ^ a = b
4. 計算散列碼
HashMap中在使用put函數插入值,會先計算當前元素的hash值,來計算該元素在hashtable中的存儲位置。
int hash = key.hashCode(); hash ^= (hash >>> 20) ^ (hash >>> 12); int h = hash ^ (hash >>> 7) ^ (hash >>> 4);
散列的本意就是要儘可能均勻分佈,通過上面的計算,能夠把「1」變的均勻一點:
before:12539 = 00000000 00000000 00110000 11111011 after:13206 = 00000000 00000000 00110011 10010110