如何使用循环在javascript中将数字增加0.01?

时间:2013-10-10 08:23:20

标签: javascript math for-loop floating-point

问题

我试图通过从1.20米开始到最后2.50米的meteres在控制台中建立一个高度列表。

我使用了这段代码:

var heights = [];
for ( var i=1.20, l=2.5; i<l; i+=0.01 ){

    heights.push(i);

}

heights = heights.join('\n');

如果我console.log( heights )我得到了:

1.2
1.21
1.22
1.23
...

然后在1.37我开始得到:

1.37
1.3800000000000001
1.3900000000000001
1.4000000000000001
1.4100000000000001
1.4200000000000002
1.4300000000000002

问题

  • 发生了什么事?
  • 我该如何解决?

演示

如果你懒得在你的控制台中输入它,那么这是 a demo : - )

6 个答案:

答案 0 :(得分:15)

你做得很好。问题在于浮点数的不准确性。

Why are floating point numbers so inaccurate?

如果您希望显示此号码,请使用:

heights[i].toFixed(2);

请注意,toFixed()返回一个字符串,如果要执行更多数值运算,则必须转换回float(parseFloat())。

答案 1 :(得分:8)

这只是因为数学如何在JavaScript中运行,你可以找到许多解释它的答案 - 比如this。 最简单的解决方案是只做100次的所有时间,然后在添加到数组时进行划分,例如

var heights = [], i, l;
for (i = 120; i < 250; i += 1){    
    heights.push(i / 100);    
}

您可以使用toFixed,但结果会为您提供String

答案 2 :(得分:2)

这是由于内部存储了浮点数,它不是特定于JavaScript的。您可以使用.toFixed()存储具有所需精度的数字的字符串表示形式,因此:

heights.push(i.toFixed(2));

如果您想避免存储字符串然后将它们转换回实际数字,您可以将该步骤相乘以使其成为整数然后存储除法:

for (var i = 120; i <= 250; ++i) {
    heights.push(i / 100);
}

除了您现在拥有数字这一事实之外,差异在于0.1的倍数以单一精度表示,例如2.4代替"2.40"

答案 3 :(得分:1)

这是因为机器使用基数2,并且您正在使用无法使用浮点数在基数2中准确表示的基数10。

您可以使用此库对其进行格式化:https://github.com/dtrebbien/BigDecimal.js

答案 4 :(得分:1)

如上所述,toFixed()返回StringparseFloat()String转换为FloatparseFloat()也删除尾随零,这是有道理的,但不适用于我的用例。

以下是使用Float并保留尾随零的迭代示例。

var i = 0.9,
  floats = [];

while (i < 2) {
  i = (i + 0.1).toFixed(1);
  floats.push(i);
  i = parseFloat(i);
}
console.log(floats);


[ '1.0',
  '1.1',
  '1.2',
  '1.3',
  '1.4',
  '1.5',
  '1.6',
  '1.7',
  '1.8',
  '1.9',
  '2.0' ]

如果不需要尾随零,则循环可以简化为:

while (i < 2) {
  floats.push(i);
  i = parseFloat((i + 0.1).toFixed(1));
}

答案 5 :(得分:0)

使用方法toFixed(float)来限制逗号后的数字量

heights.push(i.toFixed(2));