当前位置: 首页 > 面试题库 >

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

笪欣嘉
2023-03-14
问题内容

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

23.53 + 5.88 + 17.64 = 47.05

23.53 + 17.64 + 5.88 = 47.050000000000004

双方的Java和JavaScript的返回相同的结果。

我知道,由于以二进制表示浮点数的方式,某些有理数( 例如1/3-0.333333 … )无法精确表示。

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


问题答案:

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

它将根据值的大小更改四舍五入的点。作为示例 _样的_事情,我们所看到的,我们假装的,而不是二进制浮点,我们用的是十进制浮点类型有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。(这是埃里克·利珀特(EricLippert)在回答中指出

重要的是要注意,在所有情况下,右侧第一行的值都相同-因此,尽管重要的是要理解十进制数字(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被执行了。

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

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

  • 问题内容: 为什么这些逻辑运算符返回一个对象而不是布尔值? 我想了解为什么它返回(如果已定义)OR的结果,而不返回布尔结果。 问题答案: 将返回布尔值。 更新 请注意,这是基于我的测试。我不会被完全依赖。 它是一个 不 赋值或 不 赋值的表达式。而是分配计算的值。 让我们看一下这个表达式。 表达式示例: 您的表情: 另一个表达: 另一个表达: