发布于:2007-05-12 18:37:12
来自:水利工程/水利软件
[复制转发]
ROUND的奇怪结果
=ROUND((1601.3-1600)*0.05,2) =0.06
=ROUND(1.3*0.05,2) =0.07
这是什么原因呢?
我用公式求值看看发现ROUND((1601.3-1600)*0.05,2) =ROUND(1.29999999999995*0.05,2) =0.06
真奇怪,也就是1601.3-1600=1.2999999999995而不是1.3,真晕!
附件在4楼,大家下载看看吧!
全部回复(12 )
只看楼主 我来说两句经常在知道里看到 Round 函数的问题,很多人都认为这个函数就是四舍五入算法,其实是错误的。
在 VB, VBScript, C#, J#, T-SQL 中 Round 函数都是采用 Banker’s rounding(银行家舍入)算法,即四舍六入五取偶。事实上这也是 IEEE 规定的舍入标准。因此所有符合 IEEE 标准的语言都应该是采用这一算法的。
虽然“四舍五入”是我国最早提出的算法,值得我们自豪,但不能因此就认为它始终是先进的。毕竟它已经有近二千年历史了(大约一千七百多年前,天文学家杨伟就已明确提出了“四舍五入法”)。
四舍五入算法逢五就要进位,带来的问题就是结果偏大,尤其是在大量的数据统计中。例如:
原始数据
四舍五入
Banker 舍入
1.1249
1.12
1.12
1.1248
1.12
1.12
1.1252
1.13
1.12
1.1250
1.13
1.12
1.1354
1.14
1.14
1.1351
1.14
1.14
1.1352
1.14
1.14
1.1353
1.14
1.14
1.1361
1.14
1.14
1.1360
1.14
1.14
1.1313
1.1340
1.1320
这组原始数据它们的平均值是1.1313;如果我们按四舍五入保留两位小数,它们的平均值是1.134,误差是+0.0027;如果我们采用 Banker 舍入,结果是1.1320,误差是+0.0007。可以看出四舍五入的误差要大得多。而在金融计算和统计中是精度是非常重要的,这也是 Banker 舍入的名称的由来,银行家是不喜欢四舍五入的。
四舍五入是我上小学时数学课程的内容,大多数中国人都坚信舍入小数时应该使用这个算法。所幸据说现在的小学数学课程已经将 Banker’s rounding 正式写入课本。以后的孩子大概不会再有现在的问题了。
关于编程中 Round 函数和 Banker 舍入的信息,可以参考微软的 Knowledge Base:
Q194983 PRB: Round Function Different in VBA 6 and Excel Spreadsheet
Q196652 HOWTO: Implement Custom Rounding Procedures
补充:iehx提到概率,Banker 舍入确实是在统计概率上解决了这个问题。
舍1——入9
舍2——入8
舍3——入7
舍4——入6
可以看出 1,2,3,4 对应 9,8,7,6,这样在概率上讲是均等的。5 比较特殊,如果舍就会偏小,如果入就会偏大,Banker 舍入法是取最接近的偶数,这样就比四舍五入准确性高。
回复 举报
回复 举报