四捨五入之銀行家演算法

qdrzq發表於2014-06-10

對於“四捨五入”的概念,相信大家都熟悉,因為小學三四年級就已經接觸過了,常規演算法這兒從略。
但對於銀行家演算法,也許有不少人比較生疏。此前,曾經聽說過銀行家演算法,也知道演算法“四捨六入五取偶”的具體實現方法,那就是:(假設對小數部分進行舍入的話),
待舍入的部分恰好為0.5000,則需要看前面一位數的奇偶性,奇數則入,偶數則舍。
舉幾個例子來描述一下,比如:
11.5000 -> 12
12.5000 -> 12
13.5000 -> 14
14.5000 -> 14
…… ……
儘管知道了這些,但卻從來沒有深入的想,為什麼要這麼做。

偶然間,遇到了一個業務方面的問題,有客戶反映,一個業務系統產生了兩組資料:
第一組,(銷售,成本,毛利)=(0.75,0.68,0.08),銷售不等於成本和毛利的和,其原因是:
售價50,進價45,數量是0.015,這樣計算得到的成本是0.675,毛利是0.075,成本和毛利兩個欄位都是number(19,2),都五入導致;
第二組,(銷售,成本,毛利)=(0.85,0.77,0.09),也是銷售不等於成本和毛利的和,原因同樣是:
售價50,進價45,數量是0.017,這樣計算得到的成本是0.765,毛利是0.085,成本和毛利都五入導致;

這時,才深入思考了一下銀行家演算法。

按常規的四捨五入演算法
…… ……
[0.5,1.5) = 1
[1.5,2.5) = 2
[2.5,3.5) = 3
[3.5,4.5) = 4
[4.5,5.5) = 5
[5.5,6.5) = 6
…… ……
那麼,較真的人就會問,為什麼是左閉右開,而不採用左開右閉?其實道理是一樣的,左閉右開會讓恰好為n+0.5的數值全部入,而左開右閉則全部舍。
總之,兩者都會使數值有向一端的傾向性。所以,就有人提出銀行家演算法。
銀行家演算法
…… ……
(0.5,1.5) = 1
[1.5,2.5] = 2
(2.5,3.5) = 3
[3.5,4.5] = 4
(4.5,5.5) = 5
[5.5,6.5] = 6
…… ……
這樣,隔一個n+0.5數值入,隔一個舍,從而使數值趨於均衡.
以上面兩組資料為例,得到的結果是:
第一組,(銷售,成本,毛利)=(0.75,0.68,0.08)
第二組,(銷售,成本,毛利)=(0.85,0.76,0.08)
雖然仍然是不相等,但看整體效果(兩行加起來),1.60=1.44+0.16則是相等的.

這兒,說明一下,Oracle的四捨五入是常規演算法.而一些開發工具,比如VB、Delphi等等,則是使用銀行家演算法。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29512902/viewspace-1179479/,如需轉載,請註明出處,否則將追究法律責任。

相關文章