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

Mas*_*oud 3 delphi rounding

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

PS:代码------> Roundto(1.5,0)

PS 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`
Run Code Online (Sandbox Code Playgroud)

所以

`roundto(a, -1) - roundto(b, -1) = 3675.1`
Run Code Online (Sandbox Code Playgroud)

他们进来了

`c = 3675.05`
Run Code Online (Sandbox Code Playgroud)

我追踪了这个程序.它说的是一台计算机,round(c, -1) = 3675.1而另一台计算机则说round(c, -1) = 3675.0

xan*_*tos 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,if round(c, -1) = 3675.1是true还是false等等.如果你想探索fp世界,试试这个:http://pages.cs.wisc.edu/~rkennedy/exact-float

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

如果你想制作数学技巧,请使用货币类型(它是一个固定点数,并没有这些问题).

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

  • @DavidHeffernan因为OP在问题中所写的5次中有5次不是真正发生的事情!所以我推断了它,最后这个问题的"阶级"通过"银行家舍入的知识"或"fp是什么的知识"来解决.如果你在谷歌周围寻找Delphi RoundTo(或C#Math.Round),这些都是这些人的"问题". (3认同)
  • 对于"银行家四舍五入"的+1我现在已经是一名特许会计师10年了,但我可以告诉你,没有人使用这种大脑死亡.我们或者只是因为小数是无关紧要的或者是正确的. (2认同)