两个不同计算机中的奇怪RoundTo函数行为

时间:2011-10-11 06:58:40

标签: delphi rounding

问题很简单而且很奇怪! 我在Delphi中编写了一个程序并使用了roundto函数。在一台计算机中,1.5舍入为2,而在另一台计算机中,舍入为1。 怎么会发生这种情况?

P.S:Code ------> Roundto(1.5,0)

P.S 2:似乎需要更多信息,所以我发布更详细的细节。我写了一个程序。他们输入了两个数字:a = 7231.76 b = 3556.71 现在他们可以输入第三个数字c,如果c> = a - b但我的代码中的确切形式是

`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

1 个答案:

答案 0 :(得分:9)

我会说你遇到了“银行家的舍入”问题,你发布了错误的数据:-) 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

第四种可能性:如果您使用Single或Double,则更改3675.05的舍入。单身它是3675.1,双倍它是3675 ​​:-)啊......花车的神奇世界: - )

如果您想制作数学技巧,请使用货币类型(这是固定点数,并且没有这些问题)。

最后一种可能性,但它很不可能:Intel CPU将Double操作的中间结果存储为80位fp,然后在输出时将它们“舍入”为64位。一些编译器/语言引入了可选的优化(如果可能,在程序运行时激活),以使用某些处理器中存在的SSE2操作码而不是处理器的FPU。 SSE2以64位fp运行,因此不会向上转换为80位,而是从80位向下转发。这可能会导致你所看到的。请阅读Differences between x87 FPU and SSE2