对于 i 的什么值,而 (i == i + 1) {} 永远循环?

2022-08-31 08:58:18

我在英国大学考试的高级编程课程中跨过这个益智游戏

考虑以下循环,其中 i 到目前为止尚未声明:

while (i == i + 1) {}

找到此循环前面的 的定义,以便 while 循环永远持续下去。i

下一个问题,它对此代码片段提出了相同的问题:

while (i != i) {}

对我来说是显而易见的。当然,在另一种情况下,情况确实如此,但我真的被困在了前一种情况下。这与溢出有关吗?什么会导致这样的循环在Java中永远循环?NaN


答案 1

首先,由于循环不改变 的值,使此循环无限等价于选择满足的值。while (i == i + 1) {}iii == i + 1

有许多这样的值:

让我们从“异国情调”开始:

double i = Double.POSITIVE_INFINITY;

double i =  Double.NEGATIVE_INFINITY;

这些值满足的原因在 JLS 15.18.2 中
说明。数值类型的加法运算符 (+ 和 -):i == i + 1

无穷大和有限值之和等于无限操作数。

这并不奇怪,因为将有限值添加到无限值应该产生无限值。

也就是说,该满足的大多数值只是大(或)值:ii == i + 1doublefloat

例如:

double i = Double.MAX_VALUE;

double i = 1000000000000000000.0;

float i = 1000000000000000000.0f;

和 类型的精度有限,因此,如果采用足够大的值,则向其添加将产生相同的值。doublefloatdoublefloat1


答案 2

这些谜题在Joshua Bloch和Neal Gafter的“Java Puzzlers: Traps, Pitfalls, and Corner Cases”一书中有详细描述。

double i = Double.POSITIVE_INFINITY;
while (i == i + 1) {}

艺术

double i = 1.0e40;
while (i == i + 1) {}

两者都将导致无限循环,因为添加到足够大的浮点值不会改变该值,因为它不会“弥合与其后继者1的差距”。1

关于第二个谜题的说明(供未来的读者使用):

double i = Double.NaN;
while (i != i) {}

还会导致无限循环,因为 NaN 不等于任何浮点值,包括其本身 2


1 - Java益智游戏:陷阱、陷阱和角落案例(第4章 - Loopy Puzzlers)。

2 - JLS §15.21.1


推荐