前提知識:
1. 計算機中對於有符號數的表示有三種方式,原碼,補碼,反碼。
2. 在Java中,二進制數最高位是符號位,0表示正數,1表示負數;
3. 正數的表示,例如byte/int 數3, 二進制就是 0000 0011,負數的表示稍微麻煩一點(負數在計算機中是以補碼的形式存儲的)
-5 的二進制:
1. -5的絕對值二進制表示 0000 0101
2. 然后求這個數的反碼 1111 1010
3. 將反碼加1 變成 1111 1011 , 這個就是-5的二進制表示(補碼)
移位運算:
1. << 左移 (正負數一樣)
例如 5 << 2,
5 的二進制 0101 , 5 << 2 變成 010100, 結果為 5 * 2 的 n次方 (n是移動位數)= 20
例如 -5 << 2,
-5 的二進制 1111 1011 , 5 << 2 變成 1110 1100, 結果為 -5 * 2 的 n次方 (n是移動位數)= -20
說明,從負數二進制轉成10進制, - 1 ,然后取反, 加上符號位。 1110 1100 -1 = 1110 1011, 取反 0001 0100 = 20, 加上符號位 -20
代碼:
2. >> 右移
例如 int 32位 65 >> 2 ,
65的二進制數 1000001 ,右移 補0 , 65 >> 2為 0010000, 65 / 2^n = 65 / 4 = 16.
-65的二進制數據 10111111,右移補1, -65 >> 2 為 11101111 (-17)
負數-x的除法可以用以下方法來代替:
(x + 2^N - 1) >> N
-65 右移二位為 65 + 2^2 - 1 >> 2 , 然后加上符號位。
2.1 有一種情況,如果移動位數超過最大位數,例如int數超過32位,循環移位其實是一樣的,用移動位數%32,就是移動位數。
例如 65 移動34位,就是等同於移動2位(34 % 32 )
3. >>> 邏輯右移
例如 int -65 >>> 2
65的二進制數 11111111111111111111111110111111,
邏輯右移2位 00111111111111111111111111101111 變成無符號正整數