为什么更改求和顺序会返回不同的结果?
23.53 + 5.88 + 17.64
= 47.05
23.53 + 17.64 + 5.88
= 47.050000000000004
两者Java和 JavaScript返回相同的结果。
我了解,由于 float 以二进制表示的方式,一些有理数(如 1/3 - 0.333333...)无法精确表示。
为什么简单地改变元素的顺序会影响结果?
最佳答案
Maybe this question is stupid, but why does simply changing the order of the elements affects the result?
它将根据值的大小更改值的四舍五入点。作为我们所看到的种类的一个例子,让我们假设我们使用的是具有 4 个有效数字的十进制浮点类型而不是二进制浮点类型,其中每个加法都在 "无限”精度,然后四舍五入到最接近的可表示数字。这是两个总和:
1/3 + 2/3 + 2/3 = (0.3333 + 0.6667) + 0.6667
= 1.000 + 0.6667 (no rounding needed!)
= 1.667 (where 1.6667 is rounded to 1.667)
2/3 + 2/3 + 1/3 = (0.6667 + 0.6667) + 0.3333
= 1.333 + 0.3333 (where 1.3334 is rounded to 1.333)
= 1.666 (where 1.6663 is rounded to 1.666)
我们甚至不需要非整数来解决这个问题:
10000 + 1 - 10000 = (10000 + 1) - 10000
= 10000 - 10000 (where 10001 is rounded to 10000)
= 0
10000 - 10000 + 1 = (10000 - 10000) + 1
= 0 + 1
= 1
这可能更清楚地表明,重要的部分是我们有有限数量的有效数字 - 而不是有限数量的小数位。如果我们可以始终保持相同的小数位数,那么至少通过加法和减法,我们会很好(只要值没有溢出)。问题是当你得到更大的数字时,会丢失更小的信息——在这种情况下,10001 被四舍五入到 10000。 (这是 Eric Lippert noted in his answer 问题的一个例子。)
请务必注意,右侧第一行的值在所有情况下都是相同的 - 因此,尽管了解您的十进制数(23.53、5.88、17.64)不会完全表示为double
值,这只是一个问题,因为上面显示的问题。
关于java - 为什么更改总和顺序会返回不同的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19820297/