当前位置: 首页 > 知识库问答 >
问题:

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

谭炎彬
2023-03-14

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

23.53+17.64+5.88=47.050000000000004

Java和JavaScript都返回相同的结果。

我知道,由于浮点数在二进制中的表示方式,一些有理数(如1/3-0.333333...)不能精确表示。

为什么简单地改变元素的顺序会影响结果?

共有1个答案

孙昂然
2023-03-14

也许这个问题很愚蠢,但为什么简单地改变元素的顺序会影响结果呢?

它将根据值的大小改变取整值的点。作为我们所看到的一个例子,让我们假设我们使用的不是二进制浮点,而是带有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在他的回答中提到的问题的一个例子。)

重要的是要注意,右边第一行的值在所有情况下都是相同的--因此,尽管重要的是要理解十进制数(23.53、5.88、17.64)不会精确地表示为double值,但这只是由于上面所示的问题造成的问题。

 类似资料:
  • 问题内容: 为什么更改总和顺序会返回不同的结果? = = 双方的Java和JavaScript的返回相同的结果。 我知道,由于以二进制表示浮点数的方式,某些有理数( 例如1/3-0.333333 … )无法精确表示。 为什么简单地更改元素的顺序会影响结果? 问题答案: 也许这个问题很愚蠢,但是为什么仅仅改变元素的顺序会影响结果呢? 它将根据值的大小更改四舍五入的点。作为示例 _样的_事情,我们所看

  • 问题内容: 我有一个简单的Java类,如下所示: 这段代码的输出是这样的: 为什么s不在finally块中覆盖,而是控制打印输出? 问题答案: 在与所述的执行块完成语句和的值在时间语句执行是由该方法返回的值。finally子句稍后s(在语句完成之后)更改值的事实(此时)并未更改返回值。 请注意,以上内容处理的s是对块中自身值的更改,而不是对s引用对象的更改。如果s是对可变对象的引用(String不

  • 当我执行普通Select时,返回正确的结果,但当我执行Select for DB uptime时,它始终返回相同的第一个结果。我确实检查了Postgres日志,我看到select被执行了。

  • 如果在表中插入了项,然后我编写了一个查询,例如,为什么结果不是按照我期望的顺序?

  • 我试图通过执行器学习使用线程池。我试图打印的阶乘结果的数字从1到10(不一定在相同的顺序),无论先完成,然后让线程Hibernate1-5秒,这将选择为随机。 以下是我的可调用任务: } 这是我的主要课程: 我在Eclipse上运行了10次这个程序,每次输出都保持不变。 然后通过命令提示符编译,然后在那里运行。输出与eclipse不同,但再次运行多次将在此处产生相同的输出。 为什么输出不是随机的?

  • 以下代码在使用JDK 8和JDK 9运行时有不同的结果。 在JDK 8(版本1.8.0_172)下,代码打印: 但是使用JDK 9(版本9.0.1),代码返回: 我已经检查了两个JDK版本,它们是正确的。为什么代码会产生不同的结果?我的程序有什么问题吗?