For what value of i does while (i == i + 1) {} loop forever?

JavaLoopsTypes

Java Problem Overview


I ran cross this puzzler from an advanced programming course at a UK university exam.

Consider the following loop, in which i is, so far, undeclared:

while (i == i + 1) {}

Find the definition of i, that precedes this loop, such that the while loop continues for ever.

The next question, which asked the same question for this code snippet:

while (i != i) {}

was obvious to me. Of course in this other situation it is NaN but I am really stuck on the prior one. Does this have to do with overflow? What would cause such a loop to loop for ever in Java?

Java Solutions


Solution 1 - Java

First of all, since the while (i == i + 1) {} loop doesn't change the value of i, making this loop infinite is equivalent to choosing a value of i that satisfies i == i + 1.

There are many such values:

Let's start with the "exotic" ones:

double i = Double.POSITIVE_INFINITY;

or

double i =  Double.NEGATIVE_INFINITY;

The reason for these values satisfying i == i + 1 is stated in
JLS 15.18.2. Additive Operators (+ and -) for Numeric Types:

>The sum of an infinity and a finite value is equal to the infinite operand.

This is not surprising, since adding a finite value to an infinite value should result in an infinite value.

That said, most of the values of i that satisfy i == i + 1 are simply large double (or float) values:

For example:

double i = Double.MAX_VALUE;

or

double i = 1000000000000000000.0;

or

float i = 1000000000000000000.0f;

The double and float types have limited precision, so if you take a large enough double or float value, adding 1 to it will result in the same value.

Solution 2 - Java

These puzzles are described in detail in the "Java Puzzlers: Traps, Pitfalls, and Corner Cases" book by Joshua Bloch and Neal Gafter.

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

or:

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

both will result in an infinite loop, because adding 1 to a floating-point value that is sufficiently large will not change the value, because it doesn't "bridge the gap" to its successor1.

A note about the second puzzle (for future readers):

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

also results in an infinite loop, because NaN is not equal to any floating-point value, including itself 2.


1 - Java Puzzlers: Traps, Pitfalls, and Corner Cases (chapter 4 - Loopy Puzzlers).

2 - JLS §15.21.1

Solution 3 - Java

double i = Double.POSITIVE_INFINITY;

Solution 4 - Java

Just an idea: what about booleans?

bool i = TRUE;

Isn't this a case where i + 1 == i?

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionjake mckenzieView Question on Stackoverflow
Solution 1 - JavaEranView Answer on Stackoverflow
Solution 2 - JavaOleksandr PyrohovView Answer on Stackoverflow
Solution 3 - JavaFarcas GeorgeView Answer on Stackoverflow
Solution 4 - JavaDominiqueView Answer on Stackoverflow