我试图通过从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 : - )
答案 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()返回String
,parseFloat()将String
转换为Float
。 parseFloat()
也删除尾随零,这是有道理的,但不适用于我的用例。
以下是使用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));