两台不同计算机中的奇怪 RoundTo 函数行为
问题简单又奇怪! 我在Delphi中编写了一个程序并使用了roundto函数。在一台计算机中 1.5 四舍五入为 2,而在另一台计算机中则四舍五入为 1。 怎么会发生这种事?
PS:代码------> Roundto(1.5, 0)
PS 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
The problem is simple and strange!
I wrote a program in Delphi and used roundto function. In one computer 1.5 is rounded to 2 and in another computer it is rounded to 1.
How could this happen?
P.S: Code------> Roundto(1.5, 0)
P.S 2: It seems more information is needed so I post more exact detail. I wrote a program. They entered two number: a=7231.76 b=3556.71
Now they can enter a third number c if c >= a - b but the exact formation in my code is
`roundto(c, -1) >= roundto(a, -1) - roundto(b, -1)`
`roundto(a, -1) = 7231.8`
`roundto(b, -1) = 3556.7`
so
`roundto(a, -1) - roundto(b, -1) = 3675.1`
they entered
`c = 3675.05`
I traced the program. In one computer it says round(c, -1) = 3675.1
and in another computer it says round(c, -1) = 3675.0
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我想说你遇到了“银行四舍五入”问题,并且你发布了错误的数据:-)
Delphi RoundTo 实现了银行家的舍入:以 0.5 结尾的奇数向上舍入,这是传统行为,但是...以 0.5 结尾的偶数向下舍入!
因此 1.5 舍入为 2.0,但 2.5 舍入为 2.0(链接到 RoundTo< 的参考/a>)
第二种可能性:http://www.merlyn.demon.co.uk/pas-chop.htm#DRT Delphi 的某些版本中存在错误。你们所有的机器上都有相同版本的Delphi吗?
第三种可能性:你说的是浮点数!它们不是确切的数字!将它们相加和相减会创建一个通常看不见的小数微观世界 0.1 + 0.2 != 0.3!!也许您看到的 0.5 并不完全是 0.5,而是 0.49999999 或 0.500000001。如果您想检查它,请进入调试器并检查
c = 3675.05
(逻辑表达式)是 true 还是 false,如果round(c, -1) = 3675.1
> 是真是假等等。如果您想探索 fp 世界,请尝试以下操作:http://pages.cs。 wisc.edu/~rkennedy/exact-float第四种可能性:如果您使用 Single 或 Double,则 3675.05 的舍入会发生变化。 Single 是 3675.1,Double 是 3675 :-) 啊...浮点数的神奇世界 :-)
当你想玩数学技巧时,请使用Currency 类型(它是一个定点数,没有这些)问题)。
还有最后一种可能性,但可能性很小:Intel CPU 将 Double 运算的中间结果存储为 80 位 fp,然后在输出时将它们“舍入”为 64 位。一些编译器/语言引入了可选的优化(如果可能的话,在程序运行时激活)以使用某些处理器中存在的 SSE2 操作码而不是处理器的 FPU。 SSE2 在 64 位 fp 上运行,因此不会向上转换为 80 位,也不会从 80 位向下转换。这可能会导致您所看到的情况。请阅读此处x87 FPU 和 SSE2 之间的差异。
I would say you encountered the "banker's rounding" problem, and you posted the wrong data :-)
Delphi RoundTo implements the banker's rounding: Odd numbers that end in .5 are rounded upwards, that's the traditional behavior, but... Even numbers that end in .5 are rounded downwards!
So 1.5 is rounded to 2.0, but 2.5 is rounded to 2.0 (link to a reference of RoundTo)
Second possibility: http://www.merlyn.demon.co.uk/pas-chop.htm#DRT there is a bug in certain versions of Delphi. Do you have the same version of Delphi in all the machines?
Third possibility: you are speaking of floating points! They aren't exact numbers! Adding and subtracting them creates a microworld of decimals normally invisible 0.1 + 0.2 != 0.3!! Perhaps what you see as .5 isn't exactly .5 but is .49999999 or .500000001. If you want to check it, step into the debugger and check if
c = 3675.05
(the logical expression) is true or false, ifround(c, -1) = 3675.1
is true or false and so on. If you want to explore the fp world, try this: http://pages.cs.wisc.edu/~rkennedy/exact-floatFourth possibility: the rounding of 3675.05 changes if you are using Single or Double. With Single it's 3675.1, with Double it's 3675 :-) Ah... the magical world of floats :-)
When you want to make mathematical tricks, please use the Currency type (it is a fixed point number and doesn't have these problems).
There is a last possibility, but it's quite improbable: the Intel CPU stores intermediate results of Double operations as 80 bits fp and then "round" them to 64 bits on output. Some compilers/languages introduce an optional optimization (that is activated on the run of the program if possible) to use the SSE2 opcodes present in some processors instead of the FPU of the processor. The SSE2 operate on 64 bits fp, so no upcasting to 80 bits and downcasting from 80 bits. This could cause what you are seeing. Read here Differences between x87 FPU and SSE2.