round是什么? -[ Exception 闲谈 算法 ]

来源: BlogBus 原始链接: http://craftsman.blogbus.com:80/s41356/index.html 存档链接: https://web.archive.org/web/20060219100038id_/http://craftsman.blogbus.com:80/s41356/index.html


程序工匠 我的职业随笔,一个IT技术人员的技术随笔。 / 首页 / 分页: 2005-11-25 16:14:39 round是什么? -[ Exception 闲谈 算法 ] 执行这个运算:round(106.5,0),他的结果是什么? 执行这个运算:round(107.5,0),他的结果是什么? 我问我的同事,他们的回答说,应该是107和108。我在QQ上问我的朋友,他们的回答是:107和108。 是的,问大多数中国程序员他们都是这么回答的。round在很多编程教材中都解释成四舍五入运算,那么对106.5和107.5的四舍五入精确到个位上,确实应该是107和108。 可是我今天写的一段.Net程序产生的结果竟然是, 106和108 ,要不是同事测试程序的时候有个正确的数据表对比,我真的会永远不知道这个问题的真正答案。 我在VS的命令窗口反复做了几次计算,都是这样的结果,怀疑是.Net的计算有Bug了,在MSDN的FCL参考手册中,翻到关于 Math.round的描述 : Returns the number nearest the specified value. 意思就是说返回最接近指定值的数字,它给的运算范例就是四舍五入,可是表达的好像确不是这个意思,而关于round很多中文翻译都是四舍五入的。 啥意思,.Net的毛病?上网Google到了一个 Blog的Post ,原来他们也发现了这个问题。最后他总结到这个运算的规律,这个.Net的Math.round并不代表四舍五入,而是 四舍六入五成双 。实际上就是四舍六入,而如果去掉的位是5则看前面一位的奇偶,偶数则舍,奇数则入。 round难道就是四舍六入五成双吗?未必,SQL的数学函数round就是四舍五入、Excel的round就是四舍五入、XPath的rund就是四舍五入。网评说,这种四舍六入五成双其实就是国际上通用的一种舍入算法,叫做 舍入算法 或者 银行家算法 ,在我国的初级数学教材中,都只介绍四舍五入算法,而对于round这个单词,大多数都译成四舍五入,因此造成了程序开发中的误用。实际上这表明了所谓的round有两种计算方法,而我国大多数人只知道一种四舍五入。想起来以前用过round的程序开发,汗!!这种误用将会造成多少损失? round(106.5)的结果是什么,看来没有绝对标准的答案,要看具体环境了。开发中更要认真参考round函数的说明文档。不过可以说绝大多数DBM的SQL的round都是四舍五入,而大多数编程语言的round采用就近舍入。blog的post认为这是微软公司开发软件的Bug或者是SQL和编程语言运算的不一致,也会造成误用。我认为这恰恰是不同环境对精确需求不同而造成的,舍入法其实更科学因此在程序运算中采用比较多,而SQL语言对数据运算要求不高,因此采用四舍五入法。 为了使用我们通用的四舍五入,一些网友提供了很多转换的方法,其中比较简洁的就是下面的一段代码: public static double Round(double value,int digite) { string strValue = value.ToString(); int index = (strValue.ToString()).IndexOf("."); if (strValue.IndexOf(".") > 0) { strValue += "1"; } return Math.Round(double.Parse(strValue),digite); } xpath1.0提供的round也是四舍五入,可是到了xpath2.0却增加了一个函数 round-half-to-even ,一眼就可以看出来,这个函数执行的就是就近舍入算法。终于有两种算法并存的环境了。 hob.mount 发表于 16:14:39 | 阅读全文 | 评论(0) | 引用Trackback(0) | 编辑 分页: 最后更新 最新评论 存档 我的链接