位運算求整數的絕對值

通過下面的位運算可以得到一個整數的絕對值

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)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章