我(i == i + 1){}永远循环的价值是什么?

jak*_*zie 118 java types loops

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

考虑以下循环,到目前为止,我是未声明的:

while (i == i + 1) {}
Run Code Online (Sandbox Code Playgroud)

找到i在此循环之前的定义,以便while循环永远持续.

下一个问题,为此代码片段提出了同样的问题:

while (i != i) {}
Run Code Online (Sandbox Code Playgroud)

对我来说很明显.当然,在另一种情况下,NaN我确实陷入了前一个问题.这与溢出有关吗?什么会导致这样的循环在Java中永远循环?

Era*_*ran 141

首先,由于while (i == i + 1) {}循环不会改变值i,因此使该循环无限等同于选择i满足的值i == i + 1.

有很多这样的价值观:

让我们从"异国情调"开始吧:

double i = Double.POSITIVE_INFINITY;
Run Code Online (Sandbox Code Playgroud)

要么

double i =  Double.NEGATIVE_INFINITY;
Run Code Online (Sandbox Code Playgroud)

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

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

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

也就是说i,满足的大多数值i == i + 1都只是大double(或float)值:

例如:

double i = Double.MAX_VALUE;
Run Code Online (Sandbox Code Playgroud)

要么

double i = 1000000000000000000.0;
Run Code Online (Sandbox Code Playgroud)

要么

float i = 1000000000000000000.0f;
Run Code Online (Sandbox Code Playgroud)

doublefloat类型已经精度有限,因此,如果你把一个足够大doublefloat价值,加上1它会导致相同的值.

  • 或者`(double)(1L << 53)` - 或`float i =(float)(1 << 24)` (9认同)
  • @Kevin为了公平对待浮点数,如果你处理无穷大或未定义的值,你也不能假设你在代数中列出的属性. (4认同)
  • @Ruslan:任何数学家都不同意.浮点数没什么意义.它们是非关联的,非自反的(NaN!= NaN),甚至不可替代(-0 == 0,但是1/0!= 1/-0).所以大多数代数机器都不适用. (3认同)
  • @Kevin虽然浮点数在一般情况下确实不太有意义,但无穷大的行为(这句话中描述的内容)是有意义的. (2认同)
  • @Kevin:恕我直言,如果他们将"正负零"符号的概念替换为正,负和无符号"无穷小"以及一个"真零",那么浮点数学可能会更有意义. NaN等于自己.真零可以在*所有*情况下表现为加性身份,并且涉及无穷小除法的操作将失去对假设无穷小为正的偏差. (2认同)
  • @Kevin我认为问题在于,我们在这里有点过于通用("大多数数学"太过于通用而无法做出任何此类陈述).你有什么样的集合和代数结构?我先走了:包括正负无穷大的整数集合**不是**有效的环.这是最基本的代数结构之一,所以我想知道你的想法. (2认同)

Ole*_*hov 64

这些谜题在Joshua Bloch和Neal Gafter的"Java Puzzlers:陷阱,陷阱和角落案例"一书中有详细描述.

double i = Double.POSITIVE_INFINITY;
while (i == i + 1) {}
Run Code Online (Sandbox Code Playgroud)

要么:

double i = 1.0e40;
while (i == i + 1) {}
Run Code Online (Sandbox Code Playgroud)

两者都会导致无限循环,因为添加1到足够大的浮点值不会改变该值,因为它不会"缩小"与其后继者之间的差距1.

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

double i = Double.NaN;
while (i != i) {}
Run Code Online (Sandbox Code Playgroud)

也导致无限循环,因为NaN不等于任何浮点值,包括自身2.


1 - Java Puzzlers:陷阱,陷阱和角落案例(第4章 - Loopy Puzzlers).

2 - JLS§15.21.1