Javascript Math Error:Inexact Floats

时间:2010-08-24 13:17:19

标签: javascript math

  

可能重复:
  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.200000000003

为什么呢?我想我可以收集价值,但为什么会这样呢?

更新 找到问题的临时解决方案。

首先乘以:

(14900*10.8)/100 = 1609.2

然而

(14898*10.8)/100 = 1608.9840000000002

为此,将10.8乘以factor(100 in this case)并调整分母:

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

我想如果可以为额外的000s执行preg_match然后相应地调整 factor ,则可以避免浮点错误。 然而,最终的解决方案是math library

4 个答案:

答案 0 :(得分:17)

Floating point值不准确。

这几乎是问题的答案。精度有限,这意味着某些数字无法准确表示。

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

IEEE 754标准浮点值不能表示例如完全0.1。这就是为什么必须非常小心地完成的数字计算。有时,解决方案是将值以美分存储为整数,而不是以美元存储为浮点值。


“浮动”点概念,模拟基数为10

要了解为什么浮点值不精确,请考虑以下类比:

  • 您只有足够的内存来记住5位数字
  • 您希望能够在尽可能宽的范围内表示值

在表示整数时,您可以表示-99999+99999范围内的值。超出这些范围的值将要求您记住超过5位数,这是(为了这个例子)你不能做到的。

现在您可以考虑使用定点表示,例如abc.de。现在,您可以表示-999.99+999.99范围内的值,最多2位精度,例如3.14-456.78

现在考虑一个浮点​​版本。在你足智多谋中,你想出了以下方案:

  

n = abc x 10 de

现在您仍然可以记住只有5位abcde,但您现在可以代表更广泛的范围数字,甚至非整数。例如:

  

123 x 10 0 = 123.0

     

123 x 10 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,又称​​系数/尾数de exponent ,又名 scale / characteristics 。像往常一样,计算机使用基数2代替10.除了记住“数字”(位,真的),它还必须记住有效数和指数的符号。

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

另见

答案 1 :(得分:3)

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

存在像this one这样的库,它们可以帮助您将舍入错误限制到实际需要它们的位置(表示为文本)。这些库并不真正处理浮点值,而是处理分数(整数值)。所以没有0.25,而是1/4等等。

答案 2 :(得分:2)

浮点值可用于在比整数值更宽的范围内有效地表示值。然而,它是有代价的:有些值无法准确表示(因为它们存储为二进制)每个负功率为10例如(0.1,0.01等)

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

当然有时你无法避免它们。在这种情况下,一些简单的指南可以帮助您最小化舍入错误:

  1. 不要减去几乎相等的值。 (0.1-0.0999)
  2. 首先添加或乘以最大值。 (100 * 10)* 0.1而不是100 *(10 * 0.1)
  3. 首先乘以,然后除。 (14900 * 10.8)/ 100而不是14900 *(10.8 / 100)
  4. 如果确切的值可用,请使用它们而不是计算它们以获得“更漂亮”的代码

答案 3 :(得分:-3)

另外,

让JavaScript弄清楚数学优先级,没有理由使用括号:

var tax1 = 14900 * 10.8 / 100
1609.2

这很神奇。请记住避免使用无用的括号。