问题很简单,很奇怪!
我用Delphi编写了一个程序,并使用了roundto函数。一台计算机中的1.5舍入为2,另一台计算机中的舍入为1。
怎么会这样
附:代码------>舍入(1.5,0)
附注2:似乎需要更多信息,因此我发布了更确切的细节。我写了一个程序。他们输入了两个数字:a = 7231.76 b = 3556.71
现在,如果c> = a-b,他们可以输入第三个数字c,但是我代码中的确切形式是
`roundto(c, -1) >= roundto(a, -1) - roundto(b, -1)`
`roundto(a, -1) = 7231.8`
`roundto(b, -1) = 3556.7`
所以
`roundto(a, -1) - roundto(b, -1) = 3675.1`
他们进入
`c = 3675.05`
我跟踪了程序。一台计算机上显示
round(c, -1) = 3675.1
,另一台计算机上显示round(c, -1) = 3675.0
最佳答案
我会说您遇到了“银行四舍五入”问题,并且您发布了错误的数据:-)
Delphi RoundTo实现银行家的四舍五入:以.5结尾的奇数向上舍入,这是传统的行为,但是...以.5结尾的偶数也向下舍入!
因此1.5舍入为2.0,但是2.5舍入为2.0(链接到RoundTo的引用)
第二种可能性:http://www.merlyn.demon.co.uk/pas-chop.htm#DRT某些版本的Delphi中存在错误。您在所有机器上都具有相同版本的Delphi吗?
第三种可能性:您正在谈论浮点数!他们不是确切的数字!加减它们会创建一个通常不可见的小数的微世界0.1 + 0.2!= 0.3 !!也许您看到的.5并不完全是.5,而是.49999999或.500000001。如果要检查它,请进入调试器并检查c = 3675.05
(逻辑表达式)是true还是false,round(c, -1) = 3675.1
是true还是false,等等。如果要探索fp世界,请尝试以下操作:http://pages.cs.wisc.edu/~rkennedy/exact-float
第四种可能性:如果使用“单”或“双”,则三舍五入为3675.05会改变。单身是3675.1,双身是3675 :-)啊...花车的神奇世界:-)
当您想进行数学技巧时,请使用“货币”类型(这是一个固定点数,没有这些问题)。
最后一种可能性,但这是不可能的:Intel CPU将Double运算的中间结果存储为80位fp,然后将它们“舍入”为输出的64位。某些编译器/语言引入了可选的优化(如果可能,可在程序运行时激活),以使用某些处理器中存在的SSE2操作码而不是处理器的FPU。 SSE2在64位fp上运行,因此不会向上广播到80位,也不会从80位向下广播。这可能会导致您看到的内容。在此处阅读Differences between x87 FPU and SSE2。