求平均值,防止溢位(只針對整數)

2021-08-16 09:15:35 字數 803 閱讀 8167

今天看到有人討論c/c++中求平均數溢位的問題。於是我便仔細的思考並查詢相關資料。我們很容易發現 (a +b) / 2, 溢位的**是加法可能產生進製運算,那麼我們只要想辦法避免進製運算就可以了。

因為要避免進製我們很自然的就可以想到位運算。我們可以將a, b分為兩個部分(從二進位制的角度來看),乙個是相等的公共部分,另乙個則是不相等的部分。我們可以發現計算平均數的進製主要是來自相等部分的相加造成的,因此我們如果直接得到這個公共部分,那麼我們就可以避免這個進製。如果我們觀察不同的部分,我們可以發現要麼是1,要麼是0。如果我們將不同的部分相加除以2,那麼就完成了,對不同部分的取平均值。我們很容易發現這兩個部分相加,就是我們的平均值。因此我們就找到了乙個不溢位的方法來計算平均數。接下來我們來幾個例子看一下:

10  二進位制  1010

14 二進位制 1110

公共部分: 1010

不同部分的和: 0100

不同部分除以2:0010

平均數 = 1010(相同部分) + 0010(不同部分的平均數) = 1100

因此二者平均數為12

以上的操作我們可以用位運算來替代:

公共部分 = a & b

不同部分的平均值 = (a ^ b) >> 1

平均值 = 公共部分 + 不同部分的平均值 = (a & b) + ((a ^ b) >> 1)

由此,我們直接就可以避免整數加法造成的溢位。仔細觀察會發現,如果整數乙個奇數乙個偶數,我們的答案就向下取整了。因此如果有需要,我們可以根據 a 和 b 的奇偶情況,手動的新增0.5來修正答案。

java 求int平均值防止溢位

start end start 2int mid start end 1它通過移位實現了除以 2,但。這樣難道不會導致溢位嗎?首先大家可以補一下 補碼 的知識。其實問題的關鍵就是這裡了 我們知道還有一種右移是 區別在於 為有符號右移,右移以後最高位保持原來的最高位。而 這個右移的話最高位補 0。所以...

位移操作和求平均值溢位

以前寫排序演算法時有用到取index平均值的運算,通常的寫法是這樣的 mid lo hi lo 2 這樣的寫法是為了防止溢位,大家應該都清楚,記得leetcode上有一道題目專門設定了這個陷阱,相加除2的方法會導致結果錯誤。最近在看arraylist系統原始碼時,看到了下面這種寫法 mid lo h...

hive UDAF求平均值

最近做資料遷移專案,把聚合部分從kettle遷移到hadoop集群上,需要寫很多聚合指令碼 在論壇是看到alipay同事寫過類似cube的udaf,拿過來執行下報錯,有幾個地方沒看多,而且沒有注釋,只好從基礎開始看,自己搞乙個,之前寫過udf所以入手還是聽快的 準備 1 實現自己的udaf需要整合u...