今天的实验课任务是《计算机导论实验五程序设计基础》。
去隔壁班布置练习的时候,无意中听P老师说起VB语言中的一些不合习惯的毛病。譬如四舍五入函数round,4.5、3.5两个参数带入的结果,答案都是4。赶忙与权威G老师在立即窗口试验了一下,真是如此。
Print Round(3.5),Round(4.5)
4
4
Print Round(5.5),Round(6.5)
6
6
哦哦,枉我教授VB若干年,一直没有留意这个函数,只是按照教科书上写的“四舍五入”给学生做个简单说明。巨汗!
为搞清楚这里面的问题,赶紧验证刚才的结果是否是因为省略round函数的第二参数造成的:
Print Round(3.5,0),Round(4.5,0)
4
4
Print Round(5.5,0),Round(6.5,0)
6
6
Print Round(3.45,1),Round(3.55,1)
3.4
3.6
说明这一结果与参数无关,VB中Round函数的算法就是如此。
不符合习惯怎么办呢?要真正实现我们习惯的四舍五入功能,譬如要在X的小数点后第a位四舍五入,可以使用表达式:int(x*10^a+0.5)/10^a。验证:
x=3.4567
a=3
?int(x*10^a+0.5)/10^a
3.457
结论:VB6中文版说这个函数是四舍五入函数,实际上这个函数采用的四舍六入五留双。VB的Round所采用的算法是这样的:
1.25留一位,则1.2=round(1.25)
如果是1.35,则1.4=round(1.35)
奇进偶不进。这样在一大串需要四舍五入的数相加相减相乘时误差小一点。
eg:1.25+1.35+1.45+1.55+1.15+1.65=8.4=round(1.25)+round(1.35)+round(……
ROUND函数符合国家和国际标准,该函数是正确的。原先的四舍五入只是一个简化。
在微软的Knowledge Base的文章:“Q194983 PRB: Round Function Different in VBA 6 and Excel Spreadsheet”和微软的Knowledge Base的文章:“Q189847 INFO: New String and Format Functions in Visual Basic 6.0”中都指出Round函数实行Banker舍入,而不是我们习惯的算术舍入(四舍五入)。大家可以参考微软的Knowledge Base的文章:“Q196652 HOWTO: Implement Custom Rounding Procedures”,它对于舍入问题有详细的讨论。