論壇上兩次看到不用比較計算最大/最小值了,第一次討論時有個人有人給出了最理想的答案。那個人說在做影象運算時,比較運算會對指令流水線效率有較大影響,因而需要另外的實現。第二次討論時找不到第一次的帖子了,於是憑著印象並查了一些資料,仔細想了想,得到了之前的答案(假定int為4個位元組):
int min(int a, int b)
int diff = b - a;
// b < a: a + (diff & -1)
// b > a: a + (diff & 0)
return a + (diff & (diff >> 31));
int max(int a, int b)
int diff = b - a;
// b < a: b - (diff & -1)
// b > a: b - (diff & 0)
return b - (diff & (diff >> 31));
int abs(int a)
int temp = (a >> 31);
return (a + temp) ^ temp;
原理上主要有兩點:
1, 整數是以補碼表示的
2, 有符號數的移位運算是算數移位(乘2和除2)而非物理移位
正數和0的補碼同原碼,負數的補碼是絕對值的反碼加1。-1的補碼表示是0xffffffff。
任何乙個非負整數(0~231-1)右移31位都是0;任何乙個負整數(-231~-1)右移31位都是-1。這樣min和max就比較容易理解了。
再看abs
a ^ -1 == ~a
a ^ 0 == a
若a非負,沒有任何變化;若a為負,加-1再取反,得到絕對值。
位運算 實現加法
用位運算實現加法也就是計算機用二進位制進行運算,32位的cpu只能表示32位內的數,這裡先用1位數的加法來進行,在不考慮進製的基礎上,如下 1 1 01 0 1 0 1 10 0 0很明顯這幾個表示式可以用位運算的 來代替,如下 1 1 01 0 1 0 1 10 0 0這樣我們就完成了簡單的一位數...
位運算 實現加法
用位運算實現加法也就是計算機用二進位制進行運算,32位的cpu只能表示32位內的數,這裡先用1位數的加法來進行,在不考慮進製的基礎上,如下1 1 01 0 1 0 1 10 0 0 很明顯這幾個表示式可以用位運算的 來代替,如下1 1 01 0 1 0 1 10 0 0這樣我們就完成了簡單的一位數加...
位運算實現加法
用位運算實現加法也就是計算機用二進位制進行運算,32位的cpu只能表示32位內的數,這裡先用1位數的加法來進行,在不考慮進製的基礎上,如下 1.1 1 0 2.1 0 1 3.0 1 1 4.0 0 0 很明顯這幾個表示式可以用位運算的 來代替,如下 1.1 1 0 2.1 0 1 3.0 1 1 ...