【问题标题】:Why does adding two decimals in Javascript produce a wrong result? [duplicate]为什么在 Javascript 中添加两位小数会产生错误的结果? [复制]
【发布时间】:2011-03-27 05:25:12
【问题描述】:

可能重复:
Is JavaScript’s Math broken?

为什么 JS 搞砸了这个简单的数学?

console.log(.1 + .2)  // 0.3000000000000004
console.log(.3 + .6)  // 0.8999999999999999

第一个示例大于正确结果,而第二个示例小于。 ???你如何解决这个问题?在执行操作之前,您是否必须始终将小数转换为整数?我是否只需要担心添加(* 和 / 在我的测试中似乎没有相同的问题)?

我已经在很多地方寻找答案。一些教程(如购物车表单)假装问题不存在,只是将值相加。大师们为各种数学函数提供了复杂的例程,或者顺便提到 JS“做得不好”,但我还没有看到解释。​​

【问题讨论】:

  • 这个问题和每个与编程相关的论坛的数千个问题可能重复。
  • 再来一次?!我们真的需要写一个常见问题解答。
  • @Andreas:我做到了。请参阅我的答案中的链接。
  • 应该有一个特殊的处理程序来处理包含字符串 9999999 的问题。

标签: javascript math floating-point addition decimal


【解决方案1】:

这不是 JS 问题,而是更通用的计算机问题。浮点数无法正确存储所有十进制数,因为它们以二进制形式存储内容 例如:

0.5 is store as b0.1 
but 0.1 = 1/10 so it's 1/16 + (1/10-1/16) = 1/16 + 0.0375
0.0375 = 1/32 + (0.0375-1/32) = 1/32 + 00625 ... etc

so in binary 0.1 is 0.00011... 

但这是无止境的。 除了计算机必须在某个时候停止。因此,如果在我们的示例中我们停在 0.00011,我们将得到 0.09375 而不是 0.1。

无论如何,这并不取决于语言,而是取决于计算机。取决于语言的是你如何显示数字。通常,该语言将数字四舍五入为可接受的表示形式。显然JS没有。

所以你要做的(内存中的数字足够准确)只是告诉 JS 在将它们转换为文本时以某种方式舍入“很好”的数字。

您可以尝试sprintf 函数,它可以让您更好地控制数字的显示方式。

【讨论】:

    【解决方案2】:

    来自The Floating-Point Guide

    为什么我的数字不是 0.1 + 0.2 加起来是一个不错的 0.3 轮,并且 相反,我得到了一个奇怪的结果,比如 0.30000000000000004?

    因为在内部,计算机使用 格式(二进制浮点) 不能准确表示一个数字 像 0.1、0.2 或 0.3 一样。

    当代码被编译或 解释,你的“0.1”已经 四舍五入到最接近的数字 格式,这会导致一个小 舍入误差甚至在 计算发生。

    该网站有详细的解释以及如何解决问题的信息(以及如何确定在您的情况下是否存在问题)。

    【讨论】:

    【解决方案3】:

    这不仅仅是 javascript 的限制,它适用于所有浮点计算。问题是 0.1 和 0.2 和 0.3 不能完全表示为 javascript(或 C 或 Java 等)浮点数。因此,您看到的输出是由于该不准确造成的。

    特别是只有某些 2 的幂和是可以精确表示的。 0.5 = =0.1b = 2^(-1), 0.25=0.01b=(2^-2), 0.75=0.11b = (2^-1 + 2^-2) 都可以。但是 1/10 = 0.000110001100011..b 只能表示为 2 的幂的无限和,语言在某些时候会切断它。正是这种斩波导致了这些轻微的错误。

    【讨论】:

      【解决方案4】:

      这对于所有编程语言都是正常的,因为并非所有十进制值都可以精确地用二进制表示。见What Every Computer Scientist Should Know About Floating-Point Arithmetic

      【讨论】:

        【解决方案5】:

        这与计算机如何处理浮点数有关。你可以在这里阅读更多信息:http://docs.sun.com/source/806-3568/ncg_goldberg.html

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-11
          • 1970-01-01
          • 2022-11-21
          • 2016-01-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多