Javascript中的数学不准确性:对重要内容使用JS安全吗?

Javascript中的数学不准确性:对重要内容使用JS安全吗?,javascript,floating-point,rounding,native-code,Javascript,Floating Point,Rounding,Native Code,我很无聊,所以我开始在控制台里胡闹,无意中发现了这个问题(忽略语法错误): 某个变量“test”有一个值,我将它乘以10K,它会突然变成不同的数字(你可以称之为舍入误差,但这取决于你需要多少精度)。然后我把这个数字乘以10,它又变回来了。 这给我提出了几个问题: Javascript的准确度如何?这是否已经确定?即,可以考虑的数字 有办法解决这个问题吗?也就是说,在Javascript中完全准确地计算(在其数据类型的限制范围内) 第二次操作后更改的编号是否应解释为“更改回原始编号”或“由于不

我很无聊,所以我开始在控制台里胡闹,无意中发现了这个问题(忽略语法错误):

某个变量“test”有一个值,我将它乘以10K,它会突然变成不同的数字(你可以称之为舍入误差,但这取决于你需要多少精度)。然后我把这个数字乘以10,它又变回来了。

这给我提出了几个问题:

  • Javascript的准确度如何?这是否已经确定?即,可以考虑的数字
  • 有办法解决这个问题吗?也就是说,在Javascript中完全准确地计算(在其数据类型的限制范围内)
  • 第二次操作后更改的编号是否应解释为“更改回原始编号”或“由于不准确而再次更改”
我不确定这是否应该是一个单独的问题,但我实际上是在尝试将数字四舍五入到小数点后的某个数量。我研究了一下,发现了两种方法:

>方法A

>方法B


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

Javascript的准确度如何

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

有办法解决这个问题吗?也就是说,在Javascript中完全准确地计算(在其数据类型的限制范围内)

否。精度限制在于数字的存储方式。浮点数没有完全的精度,因此无论您如何进行计算,当结果返回到浮点数时,都无法达到绝对精度

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

第二次操作后更改的编号是否应解释为 “更改回原始号码”或“再次更改,因为” 不准确

又变了

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


当数字“变回”时,只是因为舍入再次隐藏了精度的限制。每次计算都会增加或减少数字中的一个小误差,有时它只是碰巧使数字更接近您原来的数字。尽管它看起来更精确,但实际上精度较低,因为每次计算都会增加一点不确定性。

JavaScript内部使用64位浮点数,这是一种广泛使用的标准,通常保证16位左右的精度。您看到的错误位于数字的第17个有效位,而且非常小

有没有一种方法可以[…]完全准确地使用Javascript进行计算(在其数据类型的限制范围内)

我想说,JavaScript的数学在其数据类型的限制范围内是完全准确的。您看到的错误超出了这些限制

您是否正在处理需要更高精度的计算

第二次操作后更改的编号是否应解释为“更改回原始编号”或“由于不准确而再次更改”

数字从未真正变得比原始值更精确或更差。只有当该值转换为十进制值时,舍入误差才变得明显。但这并不是一个值“变回”为精确数字的情况。舍入误差太小,无法显示

为什么没有本机的整数到小数的函数呢?(返回整数而不是字符串的函数)


“为什么语言是这样”的问题在这里被认为不是很有效,但是很容易绕过这个限制(假设你指的是数字而不是整数)。有337个投票:
+numb.toFixed(数字),但请注意,如果您试图显示由该表达式生成的数字,则无法保证它实际仅显示六位数字。这可能是JavaScript的“取整到N个位置”函数生成字符串而不是数字的原因之一。

您看到的错误大小是3*10^-18您需要更精确的吗?上学期我上了一堂数学课,因此可以方便地进行一些快速模拟,是的。我知道,在计算购物车中的物品数量时,你不需要那种准确性,但这不是问题所在。此外,当您考虑Road <代码> 0.02548099、99 99 99 97 97 <代码> 6个小数时,您将得到<代码> 0.025480 <代码>,而不是预期的<代码> 0.025481 。突然,合成误差变为1*10^-6。这对我来说是个问题。我希望有人能回答实际问题,而不是告诉我我所需要的是错的。。我认为这是一个合理的问题。你在做什么使这个数字四舍五入?如果我执行
var n=0.025480999997;n、 toFixed(6),我得到
0.025481
。你的“实际问题”是什么?我在你的帖子中列举了六个问题,我们已经回答了其中的大部分。我稍微改变了方法A(与我在写上一篇评论时的想法相同),这导致了上一篇评论中提到的不准确。我所说的“实际问题”是指整个问题,就像SO的“提问”一样,如果我不清楚的话,我道歉
function roundNumber(number, digits) {
    var multiple = Math.pow(10, digits);
    return Math.floor(number * multiple) / multiple;
}
function roundNumber(number, digits) {
    return Number(number.toFixed(digits));
}