Javascript不正确地倍增,导致不正确的舍入

时间:2011-09-13 18:14:00

标签: javascript math parsefloat

当我拉出想要相乘的值时,它们就是字符串。所以我拉它们,将它们解析为浮点数(以保留小数位),然后将它们相乘。

LineTaxRate = parseFloat(myRate) * parseFloat(myQuantity) * parseFloat(myTaxRateRound);

这对99%的发票都有效​​,但我发现了一个非常奇怪的问题。

当它成倍增加: 78 * 7 * 0.0725

Javascript正在返回: 39.584999999999999

当您通常在计算器中进行数学运算时: 39.585

完成所有操作后,我会使用 .toFixed(2)

取出该数字并将其四舍五入

因为Javascript正在返回该数字,所以它没有四舍五入到所需的值: $ 39.59

我尝试了 Math.round(),但我仍然得到相同的数字。

我曾想过将数字四舍五入到小数点后三位,但这对我来说似乎很笨拙。

我到处搜索,我看到的是人们提到parseFloat失去了它的精度,并使用.toFixed,但是在上面的例子中,这没有帮助。

这是我为重新创建问题所做的测试脚本:

<script>
var num1 = parseFloat("78");
var num2 = parseFloat("7");
var num3 = parseFloat("0.0725");
var myTotal = num1 * num2 * num3;
var result = Math.round(myTotal*100)/100

alert(myTotal);
alert(myTotal.toFixed(2));
alert(result);
</script>

3 个答案:

答案 0 :(得分:5)

浮点数以二进制表示,而不是十进制。某些十进制数字不会精确表示。不幸的是,由于Javascript只有一个Number类,因此它不是一个非常好的工具。其他语言有不错的十进制库,旨在避免这种错误。您将不得不接受1美分的错误,实施解决方案服务器端,或者非常努力地解决这个问题。

编辑:哦!你可以做78 * 7 * 725然后除以10000,或者更精确地将小数点放在正确的位置。基本上将税率表示为非常小的一部分。不方便,但它可能会处理你的乘法错误。

答案 1 :(得分:0)

您可能会发现Accounting.js库对此有用。它有一个“改进的”toFixed()方法。

答案 2 :(得分:0)

JavaScript / TypeScript只有一个不太好的Number类。我遇到与使用TypeScript相同的问题。我使用decimal.js-light库解决了我的问题。

new Decimal(78).mul(7).mul(0.0725) returns as expected 39.585