Javascript 乘法不正确,导致舍入不正确
当我拉出想要相乘的值时,它们是字符串。所以我拉它们,将它们解析为浮点数(以保留小数位),然后将它们相乘。
LineTaxRate = parseFloat(myRate) * parseFloat(myQuantity) * parseFloat(myTaxRateRound);
这对我 99% 的发票都有效,但我发现了一个非常奇怪的问题。
当它相乘时:78 * 7 * 0.0725
JavaScript 返回:39.584999999999994
当你通常在计算器中进行数学计算时,它是: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>
When I pull the values I want to multiply, they're strings. So I pull them, parse them as floats (to preserve the decimal places), and multiply them together.
LineTaxRate = parseFloat(myRate) * parseFloat(myQuantity) * parseFloat(myTaxRateRound);
This has worked for 99% of my invoices but I discovered one very odd problem.
When it multiplied: 78 * 7 * 0.0725
Javascript is returning: 39.584999999999994
When you normally do the math in a calculator its: 39.585
When all is said and done, I take that number and round it using .toFixed(2)
Because Javascript is returning that number, it's not rounding to the desired value of: $39.59
I tried Math.round() the total but I still get the same number.
I have thought of rounding the number to 3 decimals then two, but that seems hacky to me.
I have searched everywhere and all I see is people mention parseFloat loses its precision, and to use .toFixed, however in the example above, that doesn't help.
Here is my test script i made to recreate the issue:
<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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
浮点数以二进制表示,而不是十进制。某些十进制数字将无法精确表示。不幸的是,由于 Javascript 只有一个 Number 类,因此它对于这项工作来说并不是一个很好的工具。其他语言都有不错的十进制库,旨在避免这种错误。您将不得不接受一分钱的错误,在服务器端实施解决方案,或者非常努力地解决这个问题。
编辑:哦!您可以执行 78 * 7 * 725,然后除以 10000,或者更精确地说,只需将小数点放在正确的位置即可。基本上将税率表示为一小部分以外的东西。不太方便,但它可能会解决你的乘法错误。
Floating points are represented in binary, not decimal. Some decimal numbers will not be represented precisely. And unfortunately, since Javascript only has one Number class, it's not a very good tool for this job. Other languages have decent decimal libraries designed to avoid precisely this kind of error. You're going to have to either accept one-cent errors, implement a solution server-side, or work very hard to fix this.
edit: ooh! you can do 78 * 7 * 725 and then divide by 10000, or to be even more precise just put the decimal point in the right place. Basically represent the tax rate as something other than a tiny fraction. Less convenient but it'll probably take care of your multiplication errors.
您可能会发现 Accounting.js 库对此很有用。它有一个“改进的”toFixed() 方法。
You might find the Accounting.js library useful for this. It has an "improved" toFixed() method.
JavaScript/TypeScript 只有一个 Number 类,这不太好。我在使用 TypeScript 时遇到了同样的问题。我通过使用 decimal.js-light 库解决了我的问题。
JavaScript/TypeScript have only one Number class which is not that good. I have the same problem as I am using TypeScript. I solved my problem by using decimal.js-light library.