java - 为什么更改总和顺序会返回不同的结果?

标签 java javascript floating-point

为什么更改求和顺序会返回不同的结果?

23.53 + 5.88 + 17.64 = 47.05

23.53 + 17.64 + 5.88 = 47.050000000000004

两者JavaJavaScript返回相同的结果。

我了解,由于 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/

相关文章:

java - 来自服务器的字符串无法转换为 JSONObject?

Java WebApp : Loading resource from . jar 位于 WEB-INF

java - 如何在 Junit 测试用例中模拟 Spring JDBCTemplate 执行方法

javascript - 在 asp.net mvc 中对 Controller 进行简单的 Ajax 调用

java - LeanFT & Java : Run tests in Docker containers

javascript - Angularjs ng-repeat 和子元素

javascript - 如何弹出网页元素而不删除它?

python - Numpy:检查 float 组是否包含整数

javascript - Processing.js FloatList 无法在网络上运行

c++ - 对于 BTreeMap 和其他依赖 Ord 的事物,是否有等效于 C++ 比较器对象的对象?