【问题标题】:How to work around the decimal problem in JavaScript? [duplicate]如何解决 JavaScript 中的小数问题? [复制]
【发布时间】:2010-12-13 03:05:14
【问题描述】:

可能的重复:
Strange problem comparing floats in objective-C
Is JavaScript’s math broken?
1.265 * 10000 = 126499.99999999999 ?????

看了this后发现在JavaScript中:

0.1 + 0.2 === 0.3

评估为假。

有没有办法解决这个问题?

【问题讨论】:

标签: javascript math floating-point decimal


【解决方案1】:

我发现提供准确结果的最佳且唯一的答案是使用 Decimal 库。 BigDecimal java 类已移植到 javascript,请参阅我在 this SO post 中的回答。

注意:缩放值将“治疗”问题,但不会“治愈”它。

【讨论】:

    【解决方案2】:

    怎么样

    function isEqual(a, b)
    {
      var epsilon = 0.01; // tunable 
      return Math.abs(a - b) < epsilon;
    }
    

    【讨论】:

    • @alex:我不明白您为什么将截止日期从 0.01 更改为 0.0。此函数现在将始终返回 false,即使这两个值完全相同。没有?
    • @ruakh 我也是,可能是搞错了。我会修复它:)
    【解决方案3】:

    这是所有主要编程语言中固有的二进制数问题。

    手动将十进制 0.1 (1/10) 转换为二进制 - 您会发现它有一个重复的尾数并且无法准确表示。就像试图将 1/3 表示为小数一样。

    【讨论】:

    • 问题出在二进制浮点上,而不是一般的二进制数。有十进制浮点库(虽然在 JS 中不确定)可以避免这个问题。
    • 不,这是二进制数的问题。您不能将 .1 表示为自然二进制数。 “十进制”库通过表示十进制数字或使用定点小数来绕过它。
    • 好的,是的。我应该说的是,这个问题不会影响二进制整数。
    • +1 仅用于解释问题根源的答案。 (虽然它在技术上可以精确表示,只是用无限多的位:))
    【解决方案4】:

    您应该始终使用常量(通常称为epsilon)来比较浮点数,以确定两个数字相差多少才能被视为“相等”。

    【讨论】:

      【解决方案5】:

      使用定点数学(读作:整数)在您关心这种精度的地方进行数学运算。否则,请编写一个函数,在您可以接受的“足够接近”等于的范围内比较您的数字。

      【讨论】:

        【解决方案6】:

        只是一个想法。在比较之前将所有值乘以 10000(或一些类似的大数字,只要它超过您的最大小数位数),这就是为什么它们将是整数。

        function padFloat( val ) {
          return val * 10000;
        }
        
        padFloat( 0.1 ) + padFloat( 0.2 ) === padFloat( 0.3 );
        

        【讨论】:

          【解决方案7】:

          你当然可以将每个数字相乘

          10 * 0.1 + 10 * 0.2 === 10 * 0.3
          

          计算结果为真。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-09-24
            • 1970-01-01
            • 1970-01-01
            • 2019-11-07
            • 1970-01-01
            • 1970-01-01
            • 2016-06-09
            • 2020-06-12
            相关资源
            最近更新 更多