【发布时间】:2016-04-05 11:53:44
【问题描述】:
以下代码执行无提示的逻辑错误:
const arr = [];
class Point{
constructor(){
this.x = Math.random() * 1000000;
this.y = Math.random() * 1000000;
}
}
console.time('foo');
let avg = 0;
for(let i = 0; i < 114000000; i++ ){
arr.push(new Point());
avg += arr[i].x / 1000;
}
console.log(avg, arr.length);
// shouldn't this double the avg ?
for(let i = 0; i < 114000000; i++ ){
avg += arr[i].x / 1000;
}
console.log(avg, arr.length);
console.timeEnd('foo');
CodePen - http://codepen.io/darkyen/pen/yOPMZg?editors=0010
可能的行为:
第二个for循环后变量
avg要翻倍,数组长度应该是1.14亿。我应该得到一个内存错误。
作为脚本运行时的输出:
-
avg在第二个 for 循环之后不会改变。 - 数组长度不是 114 Mil,(Chrome 2-3M,Firefox Dev 5 Mil,MS Edge 788k)。
【问题讨论】:
-
一个小提示:
avg不变是由于浮点数的精度。在某些时候,avg的值变得如此之大,以至于由于尾数的位大小,向其添加一个小数没有任何效果。 -
i<114000000可能有问题? codepen without any arrays -
@AndersTornblad
Math.random() * 1000000 / 1000在一半的情况下应该超过 500,对于像1261167461.290721这样小的数字(对于我目前的运行),这绝对不足以被舍入错误/精度所吞噬 -
啊,那是真的...如果数组停止增长(
.push()失败),将没有arr[i]可以从中获取.x属性,这更有可能是avg没有增长的原因。如果对.push()的所有调用均成功,则avg仍将因浮动错误而关闭。但是我还是不知道为什么avg在第二次循环之后没有变化。
标签: javascript