理解浮点变量

Sim*_*mon 3 javascript floating-point

有一些问题,无论如何我无法理解.

请看这个代码


<script type="text/javascript">
function math(x)
{
 var y;
 y = x*10;
 alert(y);
}

</script>
<input type="button" onclick="math(0.011)">
Run Code Online (Sandbox Code Playgroud)

点击按钮后必须提醒什么?我认为0.11,但不,它警告 0.10999999999999999 请解释这个行为.提前致谢

par*_*cle 9

好.让我试着解释一下.

浮点数要记住的基本事项是:它们占用有限的位并尝试使用base-2算法表示原始数.

如您所知,在base-2算术中,整数由它们包含的2的幂表示.因此,6将表示为4 + 2,即.以二进制为110.

为了理解如何表示小数,您必须考虑我们如何在十进制系统中表示小数.数字的小数部分(例如0.11)表示为10的反幂的倍数(因为基数是10).因此0.11实际上是1/10 + 1/100.您可以理解,这并不足以代表有限位数的所有小数.例如,1/3将是0.333333 ....以永无止境的方式.如果我们只有32位数的空格来写下数字,我们最终只会得到原始数字的近似值,即0.33333333333333333333333333333333.例如,如果乘以3而不是1,则该数字将给出0.99999999999999999999999999999999.

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

现在,尝试在base-2中表示0.11 ; 你从11/100开始,并试图找到一个小于这个数的2的逆幂.1/2不起作用,不是1/4,也不是1/8.1/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.00011100001但是它一直在继续; 你会发现总有一小部分存在.现在,我没有完成整个计算,但是在点后面放入32位二进制数字后,你仍然可能会留下一些分数(假设所有32位空间都用于表示小数部分,它不是).因此,我相信您可以理解,结果数字可能与实际值有所不同.

在您的情况下,差异是0.00000000000000001,这是1/100000000000000000 = 1/10 ^ 17,我相信你可以看到为什么你可能有这个.


mko*_*yak 5

这是因为你正在处理浮点数,这是浮点数学的预期行为.

您需要做的是格式化该数字.

如果您想知道为什么会发生这种情况,请参阅此java解释.

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

文章的快速概述是浮点试图表示一个大于 64位的值的范围,因此会有一些不精确的表示,这就是你所看到的.

  • 这很快,你读完整篇文章? (5认同)