代码之家  ›  专栏  ›  技术社区  ›  abel

Javascript数学错误:不精确浮点[duplicate]

  •  6
  • abel  · 技术社区  · 15 年前


    Is JavaScript’s Math broken?
    How is floating point stored? When does it matter?

    代码:

    var tax= 14900*(0.108);
    alert(tax);
    

    上面给出的答案是1609.2

    var tax1= 14900*(10.8/100);
    alert(tax1);
    

    上面给出的答案是1609.2000000000003

    为什么?我想我可以把这些值凑起来,但是为什么会这样呢?

    更新:

    先乘:

    (14900*10.8)/100 = 1609.2
    

    然而

    (14898*10.8)/100 = 1608.9840000000002
    

    factor(100 in this case) 并调整分母:

    (14898*(10.8*100))/10000 = 1608.984
    

    我想如果一个人能为额外的000做一个预赛然后调整 因此,可以避免浮动误差。 然而,最终的解决办法是 math library .

    4 回复  |  直到 5 年前
        1
  •  18
  •   Community CDub    5 年前

    Floating point 价值是不精确的。

    有些语言在语言级别支持任意精度的数字类型/有理数/复数等,但不支持Javascript。C和Java都不支持。

    ieee754标准浮点值不能表示。 0.1 . 有时解决方法是将以美分为单位的值存储为整数,而不是以美元为单位的浮点值。


    “浮点”概念,10进制模拟

    要了解浮点值不精确的原因,请考虑以下模拟值:

    • 您希望能够在尽可能广泛的范围内表示值

    -99999 +99999

    现在你可以考虑 定点 代表性,比如 abc.de . 现在可以表示 -999.99 +999.99 ,高达2位精度,例如。 3.14 , -456.78 等等。

    n = abc x 10 de

    a b c , d e

    123 x 10 0 = 123.0

    3 = 123,000.0

    123 x 10毫米 6 = 123,000,000.0

    123 x 10毫米 -3 = 0.123

    123 x 10毫米 -6 = 0.000123

    现在你可以代表一个大范围的数字,但请注意,你不能代表 0.1234 123,001.0 . 事实上,有很多价值观是你无法表达的。

    这就是为什么浮点值是不精确的。它们可以表示范围很广的值,但是由于内存量是固定的,因此必须牺牲精度来换取大小。


    更多技术细节

    这个 abc significand 系数/尾数 判定元件 指数 ,又名 规模/特点

    单精度浮点类型通常使用32位。双精度通常使用64位。

    另请参见

        2
  •  3
  •   extraneon    15 年前

    这种行为是浮点算术固有的。这就是为什么浮点运算不适合处理货币问题,而货币问题需要精确。

    this one ,这有助于将舍入错误限制到您实际需要它们的位置(表示为文本)。这些库实际上并不处理浮点值,而是处理(整数值的)分数。所以不是0.25,而是1/4,以此类推。

        3
  •  2
  •   neXus    15 年前

    浮点值可以有效地表示比整数值大得多的范围内的值。然而,这是有代价的:有些值不能精确地表示(因为它们是二进制存储的)每负10次方,例如(0.1、0.01等)

    如果你想要精确的结果,尽量不要使用浮点运算。

    1. 先将最大值相加或相乘。(100*10)*0.1代替100*(10*0.1)
        4
  •  -3
  •   Wladimir Palant    13 年前

    也,

    让JavaScript计算出数学优先级,没有理由使用括号:

    var tax1 = 14900 * 10.8 / 100
    1609.2
    

    这很神奇。记住不要用无用的括号。