可能重复:
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。
答案 0 :(得分:17)
Floating point值不准确。
这几乎是问题的答案。精度有限,这意味着某些数字无法准确表示。
某些语言支持语言级别的任意精度数字类型/有理数/复数,但不支持Javascript。 C和Java都没有。
IEEE 754标准浮点值不能表示例如完全0.1
。这就是为什么必须非常小心地完成的数字计算。有时,解决方案是将值以美分存储为整数,而不是以美元存储为浮点值。
要了解为什么浮点值不精确,请考虑以下类比:
在表示整数时,您可以表示-99999
到+99999
范围内的值。超出这些范围的值将要求您记住超过5位数,这是(为了这个例子)你不能做到的。
现在您可以考虑使用定点表示,例如abc.de
。现在,您可以表示-999.99
到+999.99
范围内的值,最多2位精度,例如3.14
,-456.78
等
现在考虑一个浮点版本。在你足智多谋中,你想出了以下方案:
n = abc x 10
de
现在您仍然可以记住只有5位a
,b
,c
,d
,e
,但您现在可以代表更广泛的范围数字,甚至非整数。例如:
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等)
如果您想要精确的结果,请尽量不要使用浮点运算。
当然有时你无法避免它们。在这种情况下,一些简单的指南可以帮助您最小化舍入错误:
答案 3 :(得分:-3)
另外,
让JavaScript弄清楚数学优先级,没有理由使用括号:
var tax1 = 14900 * 10.8 / 100
1609.2
这很神奇。请记住避免使用无用的括号。