Javascript for循环做坏数学

时间:2014-03-20 09:43:34

标签: javascript loops for-loop

有谁知道编程语言的核心基本功能如何能够正确/精确地进行计算?

http://jsfiddle.net/krazyjakee/v3XCQ/

var html = '';
for(var i = 0; i <= 1; i += 0.01){
     html += i + '<br />';
}
document.body.innerHTML = html;

我的问题只是为什么会发生这种情况,我该如何阻止它发生?

0
0.01
0.02
0.03
0.04
0.05
0.060000000000000005
0.07
0.08
0.09
0.09999999999999999
0.10999999999999999

3 个答案:

答案 0 :(得分:3)

为什么我的数字,如0.1 + 0.2加起来不是很好的一轮0.3,而是我得到一个奇怪的结果,如0.30000000000000004?

因为在内部,计算机使用的格式(二进制浮点)无法准确表示0.1,0.2或0.3之类的数字。

编译或解释代码时,“0.1”已经四舍五入到该格式的最接近数字,即使在计算发生之前也会导致小的舍入误差。

为什么计算机使用这样一个愚蠢的系统?

这不是愚蠢的,只是不同的。十进制数字不能准确地表示像1/3这样的数字,所以你必须舍入到0.33之类的东西 - 而且你不要指望0.33 + 0.33 + 0.33加起来为1,你呢?

计算机使用二进制数,因为它们在处理这些数字时速度更快,并且因为对于大多数计算,小数点后17位的小错误根本不重要,因为你使用的数字不是圆的(或者说(无论如何)。

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

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

如果你真的需要你的结果准确地加起来,特别是当你使用钱时:使用特殊的十进制数据类型。 如果您只是不想看到所有这些额外的小数位:只需将结果格式化为显示它时固定的小数位数。 如果没有可用的十进制数据类型,则可以使用整数,例如:完全以美分进行货币计算。但这是更多的工作,并有一些缺点。 为什么其他计算如0.1 + 0.4正常工作?

在这种情况下,结果(0.5)可以精确地表示为浮点数,并且输入数字中的舍入误差可能相互抵消 - 但这不一定是可靠的(例如,当这两个数字首先存储在不同大小的浮点表示中时,舍入误差可能不会相互抵消。)

在其他情况下,例如0.1 + 0.3,结果实际上并不是0.4,但足够接近,0.4是最接近结果的数字,而不是任何其他浮点数。然后,许多语言显示该数字,而不是将实际结果转换回最接近的小数部分。

答案 1 :(得分:0)

根据定义,浮点数学不精确。由于数字的表示精度有限,因此无法表示所有数字。

在循环中使用整数值并从中计算值。虽然这仍然是浮点值,但在数字中加一个没有那个精度问题:

var html = '';
for(var i = 0; i <= 100; i++){
  html += (i / 100) + '<br />';
}
document.body.innerHTML = html;

答案 2 :(得分:0)

var html = '';
for(var i = 0; i <= 1; i += 0.01){
     html += i.toFixed(2) + '<br />';
}
document.body.innerHTML = html;