Javascript乘法不正确,导致不正确的舍入

Javascript multiplying incorrectly, causing incorrect rounding

本文关键字:不正确 舍入 Javascript      更新时间:2023-09-26

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

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

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

78 * 7 * 0.0725

Javascript返回: 39.58499999999999994

当你用计算器做数学运算时,它是:39.585

当所有的说和做,我取这个数字并四舍五入使用.toFixed(2)

因为Javascript返回的是这个数字,所以它没有四舍五入到期望的值:$39.59

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

我想过把数字四舍五入到小数点后3位,然后2位,但这对我来说似乎很粗糙。

我到处搜索,我所看到的是人们提到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>

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

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

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

JavaScript/TypeScript只有一个Number类,这不是很好。我有同样的问题,因为我使用TypeScript。我通过使用decimal.js-light库解决了这个问题。

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