原題:
int f(int x,int y)
f(729,271)=
(x&y)+((x^y)>>1) 書上解析說這個函式的功能是取兩個數的平均數。
不太明白,查了資料加上整理一下,僅作記錄。
一種解釋是:
把x和y裡對應的每一位(指二進位制位)都分成三類,每一類分別計算平均值,最後彙總。
其中,一類是x,y對應位都是1,用x&y計算其平均值;
一類是x,y中對應位有且只有一位是1,用(x^y)>>1計算其平均值;
還有一另是x,y中對應位均為0,無須計算。
具體解釋一下怎樣計算的:
一、x,y對應位均為1,相加後再除以2還是原來的數,如兩個00001111相加後除以2仍得00001111,這是第一部分。
二、第二部分,對應位有且只有一位為1,用「異或」運算提取出來,然後》1(右移一位,相當於除以2),即到到第二部分的平均值。
三、第三部分,對應位均為零,因為相加後再除以二還是0,所以不用計算。
三部分彙總之後就是(x&y)+((x^y)>>1)
順便解釋一下前面說到可以避免溢位。
假設x,y均為unsigned char型資料(0~255,占用一位元組),顯然,x,y的平均數也在0~255之間,但如果直接x+y可能會使結果大於255,這就產生溢位,雖然最終結果在255之內,但過程中需要額外處理溢位的那一位,在彙編中就需要考慮這種高位溢位的情況,如果(x&y)+((x^y)>>1)計算則不會。
另外一種解釋是:
將a和b拆成兩部分的平均值相加:
a、b對應位相同部分,a、b對應位不同部分。
a&b計算的是兩個數用二進位制表示時對應位相同的部分的平均,由於是取平均,所以若對應位相同則取其中乙個數即可,所以用與操作;
a^b>>1計算的是對應位不同的部分的平均,也就是乙個是0乙個是1,那麼平均就是(0+1)/2,就是異或並移位
(右移一位,相當於除以2)
的結果。
舉乙個十進位制的例子:
計算14和6的平均值,拆分數字:14=6+8,6=6+0.相同部分兩個6,取乙個,不同部分8和0,取(8+0)/2=4。那麼結果就是6+4=10就是所要求的答案。
個人比較偏好第二種解釋。
參考:(x&y)+((x^y)>>1)
這篇部落格解釋了另一種方法
x y x y 1 作用及其優點
x y x y 1 作用及其優點 作用 程式設計師面試寶典 第四版39頁的題 int func int x,int y func 729,271 是多少?思路最簡單也最直接的就是將x和y都先轉換為二進位制,然後老老實實的做按位與,按位異或等運算,最後得出結果。首先說明該表示式的作用就是求兩數的平均值...
x y x y 1 求平均值
x y x y 1 把x和y裡對應的每一位 指二進位制位 都分成 三部分,每一部分 分別計算平均值,最後彙總 其中,第一部分 是x,y對應位都是1,用x y計算其平均值 第二部分 是x,y中對應位有且只有一位是1,用 x y 1計算其平均值 第二部分 是x,y中對應位均為0,無須計算。下圖詳細說明 ...
求平均數 x y x y 1 原理
x y x y 1 能求x與y的平均數,其原理1如下 設兩數如下 x y取出同為1的位,如下 00110 由此數一定小於等於原來如何乙個數,由此數加乙個數可以得到原來數,由此將原來的兩數相加變成4數相加,如下 相當於 00110乘以2 x y乘以2 而後兩數相加就是x y,相當於 x y乘以2 x ...