这个for
循环是否会停止?
for (var i=0; 1/i > 0; i++) {
}
如果是这样,何时和为什么?
发布于 2018-03-26 15:00:29
循环不会停在正确实现的JavaScript引擎中。(引擎的主机环境可能最终会终止它,因为它是无止境的,但那是另一回事。)
原因如下:
i
是这样0
,条件1/i > 0
是真的,因为在JavaScript中,1/0
是Infinity
,并且Infinity > 0
是真的。i
将会增加并且长时间继续增长为一个正整数值(再进行9,007,199,254,740,991次迭代)。在所有这些情况下,1/i
都会保留下来> 0
(尽管最终的值1/i
会变得非常小),所以循环会继续到达并包括i
达到该值的循环Number.MAX_SAFE_INTEGER
。Number.MAX_SAFE_INTEGER
(9,007,199,254,740,991)是格式可以容纳的最高正整数值,i
并且i + 1
都可以精确地表示(spec)。9,007,199,254,740,991和9,007,199,254,740,992都可以表示,但下一个整数9,007,199,254,740,993不能; 9,007,199,254,740,992之后的下一个整数是9,007,199,254,740,994。这里是位模式,注意最右边的(最不重要的)位:
+ ------------------------------------------------- --------------签位 / + ------- + ---------------------------------------- --------------指数 / / | + ------------------------------------------------- + - 有意义 / / | / | 0 10000110011 1111111111111111111111111111111111111111111111111111 = 9007199254740991(Number.MAX_SAFE_INTEGER) 0 10000110100 0000000000000000000000000000000000000000000000000000 = 9007199254740992(Number.MAX_SAFE_INTEGER + 1) x xxxxxxxxxxx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 9007199254740993(Number.MAX_SAFE_INTEGER + 2)无法存储 0 10000110100 0000000000000000000000000000000000000000000000000001 = 9007199254740994(Number.MAX_SAFE_INTEGER + 3)
请记住,格式是基数2,并且指数的最低有效位不再是小数; 它的值为2.它可以关闭(9,007,199,254,740,992)或(9,007,199,254,740,994); 所以在这一点上,即使在整数(整数)范围内,我们也开始失去精度。这对我们的循环有影响!i = 9,007,199,254,740,992
循环后,i++
再给我们...... i = 9,007,199,254,740,992
; 没有改变i
,因为下一个整数不能被存储,并且计算结束。i
如果我们这样做会改变i += 2
,但i++
不能改变它。所以我们已经达到了稳定状态:i
永远不会改变,循环也不会终止。以下是各种相关计算:
if (!Number.MAX_SAFE_INTEGER) {
// Browser doesn't have the Number.MAX_SAFE_INTEGER
// property; shim it. Should use Object.defineProperty
// but hey, maybe it's so old it doesn't have that either
Number.MAX_SAFE_INTEGER = 9007199254740991;
}
var i = 0;
console.log(i, 1/i, 1/i > 0); // 0, Infinity, true
i++;
console.log(i, 1/i, 1/i > 0); // 1, 1, true
// ...eventually i is incremented all the way to Number.MAX_SAFE_INTEGER
i = Number.MAX_SAFE_INTEGER;
console.log(i, 1/i, 1/i > 0); // 9007199254740991 1.1102230246251568e-16, true
i++;
console.log(i, 1/i, 1/i > 0); // 9007199254740992 1.1102230246251565e-16, true
i++;
console.log(i, 1/i, 1/i > 0); // 9007199254740992 1.1102230246251565e-16, true (no change)
console.log(i == i + 1); // true
https://stackoverflow.com/questions/-100004310
复制相似问题