如何处理JavaScript中的浮点数精度?

2022-08-29 22:28:16

我有以下虚拟测试脚本:

function test() {
  var x = 0.1 * 0.2;
  document.write(x);
}
test();

这将打印结果,而它应该只是打印(如果您使用计算器)。据我所知,这是由于浮点乘法精度的错误。0.0200000000000000040.02

有没有人有一个很好的解决方案,以便在这种情况下我得到正确的结果?我知道有像四舍五入这样的功能是另一种可能性,但我想真正打印出整数而没有任何切割和舍入。只是想知道你们中是否有一些漂亮,优雅的解决方案。0.02toFixed

当然,否则我会四舍五入到大约10位左右。


答案 1

浮点指南

我该怎么做才能避免这个问题?

这取决于你正在做什么样的计算。

  • 如果你真的需要你的结果精确地加起来,特别是当你使用金钱时:使用一个特殊的十进制数据类型。
  • 如果您只是不想看到所有这些额外的小数位:只需在显示结果时将结果格式化为固定的小数位数即可。
  • 如果您没有可用的十进制数据类型,另一种方法是使用整数,例如,完全以美分为单位进行货币计算。但这是更多的工作,有一些缺点。

请注意,第一点仅适用于确实需要特定的精确十进制行为的情况。大多数人不需要这个,他们只是对他们的程序不能在1/10这样的数字下正常工作而感到恼火,而没有意识到如果1/3发生相同的错误,他们甚至不会眨眼。

如果第一点真的适用于您,请使用BigDecimal for JavaScript,这根本不优雅,但实际上解决了问题,而不是提供不完美的解决方法。


答案 2

我喜欢佩德罗·拉达里亚的解决方案,并使用类似的东西。

function strip(number) {
    return (parseFloat(number).toPrecision(12));
}

与 Pedros 解决方案不同,这将向上舍入 0.999...重复,并且精确到最小有效位数的正负 1。

注意: 在处理 32 位或 64 位浮点时,您应该使用 toPrecision(7) 和 toPrecision(15) 以获得最佳结果。有关原因的信息,请参阅此问题