通過下面的位運算可以得到一個整數的絕對值
public int abs( int a ) {
return (a + (a >> 31)) ^ (a >> 31) ;
}
a爲正數的情況下
a >> 31 = 00000000 00000000 00000000 00000000
a爲負數的情況下
a >> 31 = 11111111 11111111 11111111 11111111
所以,a爲正數的情況下公式成立顯而易見,a爲負數的情況就是求a的補碼的過程的逆過程
求補碼的過程爲:
正數原碼 --> 求反得到反碼 --> 再加1得到補碼
舉個-1試試
-1的絕對值原碼
00000000 00000000 00000000 00000001
---------------------
先求反,這裏求反可以通過異或的方式得到,即
00000000 00000000 00000000 00000001
^
11111111 11111111 11111111 11111111
得到反碼
11111111 11111111 11111111 11111110
---------------------
再加1得到補碼
11111111 11111111 11111111 11111110
+
00000000 00000000 00000000 00000001
得到補碼
11111111 11111111 11111111 11111111
所以-1的補碼就爲
11111111 11111111 11111111 11111111
現在將這個過程逆向即可
現將補碼-1得到反碼,而-1在計算機裏就是+(-1)
11111111 11111111 11111111 11111111
+
11111111 11111111 11111111 11111111 ---> 發現沒,這個值等於 a >> 31
得到反碼
11111111 11111111 11111111 11111110 ---> 最高位越界直接丟失
--------------------
再將反碼轉爲原碼,一樣是通過異或操作得到
11111111 11111111 11111111 11111110
^
11111111 11111111 11111111 11111111 ---> 發現沒,這個值也等於 a >> 31
得到原碼
00000000 00000000 00000000 00000001
所以-1的原碼就爲00000000 00000000 00000000 00000001,而這個值就是-1的絕對值,爲1。
通過上面的推到過程,不難看出整數的絕對值就等於
(a + (a >> 31)) ^ (a >> 31)