Javascript 理解浮点变量

Javascript 理解浮点变量,javascript,floating-point,Javascript,Floating Point,有点问题,反正我也不明白 请看这个密码 函数数学(x) { 变量y; y=x*10; 警报(y); } 我点击按钮后必须提醒什么? 我认为0.11,但不是,它会提醒你 0.1099999999999 请解释一下这种行为。 提前感谢这是因为您正在处理浮点运算,这是浮点数学的预期行为 你需要做的是格式化这个数字 如果您想知道发生这种情况的原因,请参阅此处也适用的内容 在javascript中,所有数字都表示为64位浮点,因此您经常会遇到这种情况 那篇文章的快速概述是,浮点试图表示一个范围更大

有点问题,反正我也不明白

请看这个密码



函数数学(x)
{
变量y;
y=x*10;
警报(y);
}

我点击按钮后必须提醒什么? 我认为0.11,但不是,它会提醒你 0.1099999999999 请解释一下这种行为。
提前感谢

这是因为您正在处理浮点运算,这是浮点数学的预期行为

你需要做的是格式化这个数字

如果您想知道发生这种情况的原因,请参阅此处也适用的内容

在javascript中,所有数字都表示为64位浮点,因此您经常会遇到这种情况


那篇文章的快速概述是,浮点试图表示一个范围更大的值,然后将适合64位,因此会有一些不精确的表示,这就是您所看到的。

使用浮点数,您可以得到您试图编码的数字的表示形式。大多数情况下,这是一个与原始数字非常接近的数字。有关编码/存储浮点数的更多信息,请参见

注意
如果显示x的值,它仍然显示0.011,因为JavaScript尚未决定x的变量类型。但将其与10相乘后,类型被设置为浮点(这是唯一的可能性),并显示舍入错误。

您可以尝试使用此值修复小数的nr:

// fl is a float number with some nr of decimals
// d is how many decimals you want
function dec(fl, d) {
  var p = Math.pow(10, d);
  return Math.round(fl*p)/p;
}
例:

它的工作原理是首先将浮点数乘以
10^3
(1000)表示三位小数,或
10^2
(100)表示两位小数。然后将其旋转,并将其分回到原始大小。
Math.pow(10,d)
make
10^d
(意味着
d
将给我们1000)


在您的情况下,执行
alert(12月(y,2)),它应该可以工作。

好的。让我来解释一下

浮点数需要记住的基本点是:它们占用有限的位,并尝试使用基数为2的算术来表示原始数字

如您所知,在以2为基数的运算中,整数由其包含的2的幂表示。因此,6将表示为4+2,即二进制表示为110

为了理解分数是如何表示的,你必须考虑我们在十进制系统中是如何表示分数的。数字的小数部分(例如0.11)表示为10的反幂的倍数(因为基数是10)。因此,0.11实际上是1/10+1/100。正如您所理解的,这还不够强大,无法在有限的位数中表示所有小数。例如,1/3等于0.333333。。。。以永无止境的方式。如果我们只有32位的空格来写下这个数字,那么我们最终只能得到与原始数字0.33333333的近似值。例如,如果将该数字乘以3而不是您预期的1,则该数字将为0.99999999999999999999

base-2的情况类似。每个分数将表示为2的反幂的倍数。因此,0.75(十进制)(即3/4)将表示为1/2+1/4,这意味着0.11(以2为基数)。正如基数10不足以以有限的方式表示每个分数一样,基数2也不能在有限的空间内表示所有分数

现在,尝试在base-2中表示0.11;从11/100开始,尝试找到一个正好小于这个数字的2的逆幂1/2不起作用,1/4也不起作用,1/81/16符合要求,因此您在小数点后第4位标记1,然后从11/100中减去1/16。剩下的是19/400。现在试着找出符合描述的下一个2的幂1/32似乎就是那一个,在该点后标记第5位,然后从19/400中减去1/32,得到13/800。下一个是1/64,剩下的是1/1600,因此下一个是1/2048,等等。因此我们得到了0.0001110001,但它继续下去;你会看到,总有一小部分剩余。现在,我没有完成整个计算,但是在点后面输入32个二进制数字之后,可能还剩下一些分数(这是假设所有的32位空间都用来表示小数部分,但事实并非如此)。因此,我相信你会明白,得出的数字可能与实际值存在一定程度的差异


在您的情况下,差异是0.000000000000000001,即1/1000000000000000=1/10^17,我相信您可以理解为什么会出现这种情况。

@mkoryak no但我不明白当数字表示为32位浮点时为什么会发生变化?我现在读一下,我想我明白了:)在javascript中,所有数字都用64位浮点表示。我不明白为什么。但是如何解决呢?你已经提出了一个需要解决的问题。不,它不起作用。它“吃掉”欲望数字。但是你帮助我,我只需要使用这个,看函数dec(fl,d){var p=Math.pow(10,d);var c=fl*p*10/p;alert(c);}当我调用Math(0.011,3)时,它就工作了!!!谢谢,这不会提醒你“0.11”吗?奇怪。对我有用:)函数数学(x){vary=x*10;警报(dec(y,2));}函数dec(fl,d){varp=math.pow(10,d);返回math.round(fl*p)/p;}数学(0.011);您的函数返回0.01。它是预期的:)请原谅,如果你喂它,它会返回0.01(0.011,2)。但在名为math的函数中,最终将其输入为0.11
// fl is a float number with some nr of decimals
// d is how many decimals you want
function dec(fl, d) {
  var p = Math.pow(10, d);
  return Math.round(fl*p)/p;
}
var n = 0.0012345;
console.log(dec(n,6)); // 0.001235
console.log(dec(n,5)); // 0.00123
console.log(dec(n,4)); // 0.0012
console.log(dec(n,3)); // 0.001