4種方法,求兩個數的平均數

設 int 類型 a 和 b ,且 a>=b:

方案一:(a+b)/2;

該方案向下取整,可能會產生上溢,使程序崩潰。

方案二:無符號右移 (a + b)>>> 1;

該方案向下取整,不會產生上溢,且快於方案三。

PS:C++中沒有無符號右移,實現方法:int mid = ((unsigned)a + (unsigned)b)>>> 1;

方案三:b+(a-b)/2 或 b+(a-b)>>1;

無上溢風險。

方案四:(a&b)+((a^b)>>1)

位運算,無上溢風險。

原理:a&b 就是a和b相同位數的平均值,而(a^b)是a和b不同位數的和,所以我們需要將它右移一位,相當於除以2,即爲((a^b)>>1),最後加起來就是所求的平均值了。

推導過程:a + b = (a&b) 2 + (a^b) ——> average=((a&b)2+(a^b))/2 ——> average=(a&b) + (a^b)>>1

Eg:兩個數爲15和5。15二進制序列低位爲1111,5二進制序列低位爲0101。
按位與(&)運算後得到兩者相同的部分0101;按位異或(^)運算後得到兩者不同的部分1010。
因爲相同的部分兩者都有,所以要乘以二,再加上不同的部分(至此爲15+5)再除以2就是平均值(10)。
0101爲5,乘以2爲10,加上1010(10)爲20,再除以2就是平均值10。

發佈了19 篇原創文章 · 獲贊 10 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章