Javascript 中的数学不准确:将 JS 用于重要的东西是否安全?

DaJ*_*aJF 5 javascript floating-point rounding native-code

我很无聊,所以我开始在控制台中摆弄,并偶然发现了这个(忽略语法错误):

Chrome 控制台中的 Node.js

一些变量“测试”有一个值,我乘以 10K,它突然变成不同的数字(你可以称之为舍入误差,但这取决于你需要多少准确度)。然后我将该数字乘以 10,它又变回/再次变化。

这给我提出了几个问题:

  • Javascript 的准确度如何?这已经确定了吗?即可以考虑的数字?
  • 有没有办法来解决这个问题?即在 Javascript 中完全准确地进行数学运算(在其数据类型的限制内)。
  • 第二次操作后更改的号码应该被解释为“改回原来的号码”还是“因为不准确而再次更改”?

我不确定这是否应该是一个单独的问题,但我实际上是在尝试将数字四舍五入到小数点后的某个数量。我研究了一下,发现了两种方法:

 >方法一

function roundNumber(number, digits) {
    var multiple = Math.pow(10, digits);
    return Math.floor(number * multiple) / multiple;
}
Run Code Online (Sandbox Code Playgroud)

 >方法 B

function roundNumber(number, digits) {
    return Number(number.toFixed(digits));
}
Run Code Online (Sandbox Code Playgroud)


直觉上我更喜欢方法B(看起来更有效),但我不知道幕后发生了什么,所以我无法判断。有人对此有什么想法吗?或者一种对此进行基准测试的方法?为什么没有原生的 round_to_this_many_decimals 函数?(返回一个整数,而不是一个字符串)

Guf*_*ffa 4

Javascript 的准确度如何?

Javascript 使用标准双精度浮点数,因此精度限制与使用它们的任何其他语言(即大多数语言)相同。它是处理器用来处理浮点数的本机格式。

有没有办法来解决这个问题?即在 Javascript 中完全准确地进行数学计算(在其数据类型的限制内)。

不可以。精度限制在于数字的存储方式。浮点数不具有完全的精度,因此无论您如何进行计算,都无法实现绝对精度,因为结果会返回浮点数。

如果您想要完全准确,那么您需要使用不同的数据类型。

第二次操作后更改的号码是否应该被解释为“改回原来的号码”或“因为不准确而再次更改”?

又开始变了。

当数字转换为要显示的文本时,它会四舍五入到特定位数。那些看起来准确的数字其实并不准确,只是精度上的限制没有显现出来。

当数字“变回来”时,这只是因为四舍五入再次隐藏了精度的限制。每次计算都会在数字中添加或减去一个小的误差,有时它只是碰巧使数字更接近您最初的数字。尽管看起来更准确,但实际上不太准确,因为每次计算都会增加一些不确定性。