【问题标题】:Javascript multiplying incorrectly, causing incorrect roundingJavascript乘法不正确,导致不正确的舍入
【发布时间】:2011-11-16 09:58:47
【问题描述】:

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

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

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

当它相乘时:78 * 7 * 0.0725

Javascript 正在返回:39.584999999999994

当您通常在计算器中进行数学运算时: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 math parsefloat


【解决方案1】:

浮点数以二进制表示,而不是十进制。一些十进制数将无法精确表示。不幸的是,由于 Javascript 只有一个 Number 类,它不是一个很好的工具来完成这项工作。其他语言有不错的十进制库,旨在避免这种错误。你要么接受一分钱的错误,要么在服务器端实施解决方案,要么努力解决这个问题。

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

【讨论】:

  • 很好,我仍在使用我的 javascript 控制台来达到同样的目的。而不是 num1、num2 等。我发现说 quantity=78; price=7; taxrate=7.25; total = (quantity * price * taxrate) / 100; 更清楚...我认为将比率作为百分比并除以 100 而不是 10,000 更清楚。
  • 可能是。你应该没问题,因为美国的税率总是 (afaik) 下降四分之一个百分点,这意味着如果你将它们表示为百分比,你可以将它们完美地表示为浮点数。
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-08
      • 2012-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-24
      • 1970-01-01
      相关资源
      最近更新 更多