How can "while (i == i) ;" be a non-infinite loop in a single threaded application?

Java

Java Problem Overview


I just got a question that I can't answer.

Suppose you have this loop definition in Java:

while (i == i) ;

What is the type of i and the value of i if the loop is not an infinite loop and the program is using only one thread?

Java Solutions


Solution 1 - Java

double i = Double.NaN;

The API for Double.equals() spells out the answer: "Double.NaN==Double.NaN has the value false". This is elaborated in the Java Language Specification under "Floating-Point Types, Formats, and Values":

> NaN is unordered, so the numerical > comparison operators <, <=, >, and >= > return false if either or both > operands are NaN. The > equality operator == returns false if > either operand is NaN, and the > inequality operator != returns true if > either operand is NaN. In > particular, x!=x is true if and only > if x is NaN, and (x<y) == !(x>=y) will > be false if x or y is NaN.

Solution 2 - Java

The value of i is then Invalid. "Not a Number".

After some googling, i found out that you CAN have NaN ( Not a Number ) in Java! So, a Float Pointing number is the Data Type and the Value is NaN. See here

Solution 3 - Java

double i = Double.NaN;

NaN is not equal to anything, including itself.

Solution 4 - Java

float i = Float.NaN;
while(i == i) ;
System.out.println("Not infinite!");

Solution 5 - Java

Since others said it's NaN I got curious about the official (JDK 6) implementation of Double.isNaN, and behold:

/**
 * Returns <code>true</code> if the specified number is a
 * Not-a-Number (NaN) value, <code>false</code> otherwise.
 *
 * @param   v   the value to be tested.
 * @return  <code>true</code> if the value of the argument is NaN;
 *          <code>false</code> otherwise.
 */
static public boolean isNaN(double v) {
    return (v != v);
}

Solution 6 - Java

I'm not sure, but I believe (i == i) is not atomic operation in multithreaded process, so if i value will be changed by other thread between pushes of it's value to stack on thread executing the loop, then that condition can be false.

Solution 7 - Java

I would add

float i = Float.NaN;

as well as

double i = Double.NaN;

A common trick in these sort of questions is in the assumption you make that i is an int. Other common assumptions might be s is a String, x,y are double, ch is a char, b is a byte etc. If you see a question like this you can bet that 'i' is not its expected type.

A similar question is; This never loops, what is 'x'

while(x == x && x != x + 0) { }

Another question I quite like is; This loop is an infinite loop, what are the possible values of x. (: I count four of them, as @Clement points out below :)

while(x != 0 && x == -x) { }

Solution 8 - Java

Think of Nan as the equivalent of exception but uses a magic value within a calculation. Because a calculation failed - eg square root of a negative, divide by zero etc - it makes no sense in comparing them against anything else. After all if divide by zero is a nan is it equivalent to the square root of -2 or square root of -3 ?

Nan allows a calculation that includes a step that returns an invalid answer to complete without introducing extra exceptions. To verify the answer is value simply test for non nandness ( is that's word if not I bags it) via Float.isNan() o equivalent.

Solution 9 - Java

I know this is a Java question, but considering the question for other languages is intriguing.

In C, a simple type such as 'int' could exhibit 'terminate before the universe grows cold' behaviour if 'i' was declared as a volatile (so the compiler would be forced to do two reads of 'i' for each iteration) and if 'i' was actually in memory where something else could affect it. Then the loop would terminate when 'i' changed between the two reads of a single iteration. (Added: a possible place - in a micro-computer where 'i' is actually located at the address of an I/O port, perhaps connected to a position sensor. It would be more plausible if 'i' was a pointer variable (a pointer to volatile memory) and the statement was 'while (*i == *i);'.)

As evidenced by other answers, in C++, the '==' operator can be supplied by the user if i is of a user-defined class, so anything might be possible.

Rather like NaN, in an SQL-based language, the loop would not be infinite if the value of i was NULL; however, any non-NULL value would make the loop infinite. This is rather like Java, where any number (as opposed to NaN) makes the loop infinite.

I do not see the construct having any practical use, but it is an interesting trivia question.

Solution 10 - Java

I was surprised to not see this solution:

while (sin(x) == sin(x)) //probably won't eval to true

In response to a comment, try running this:

double x = 10.5f;
assert (x == asin(sin(x)));

x should always equal the arcsine(sin(x)) in theory, but in practice it doesn't.

Solution 11 - Java

Not infinite loop, one thread :)

import static B.*;
public class A {
    public static void main(String[] args) {
        System.out.println("Still Running");
        while (i == i) ;
    }
}


public class B {

    public static int i;
    static {
        System.exit(0);
    }
}

Solution 12 - Java

i == i is not atomic. Proved by such program:

static volatile boolean i = true;
public static void main(String[] args) throws InterruptedException
{
    new Thread() {
        @Override
        public void run() {
            while (true) {
                i = !i;
            }
        }
    }.start();

    while (i == i) ;
    System.out.println("Not atomic! i: " + i);
}

Update Here is one more example of not-infinite loop (no new threads are created).

public class NoNewThreads {
    public static void main(String[] args) {
        new NoNewThreads();
        System.gc();
        int i = 500;
        System.out.println("Still Running");
        while (i == i) ;
    }

    @Override
    protected void finalize() throws Throwable {
        super.finalize();
        Thread.sleep(1000);
        System.exit(0);
    }
}

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
QuestionZizzencsView Question on Stackoverflow
Solution 1 - JavaZach ScrivenaView Answer on Stackoverflow
Solution 2 - JavaFilip EkbergView Answer on Stackoverflow
Solution 3 - JavaBill the LizardView Answer on Stackoverflow
Solution 4 - JavaAaron MaenpaaView Answer on Stackoverflow
Solution 5 - JavaBart van HeukelomView Answer on Stackoverflow
Solution 6 - JavaokutaneView Answer on Stackoverflow
Solution 7 - JavaPeter LawreyView Answer on Stackoverflow
Solution 8 - JavamP.View Answer on Stackoverflow
Solution 9 - JavaJonathan LefflerView Answer on Stackoverflow
Solution 10 - JavajkeysView Answer on Stackoverflow
Solution 11 - JavaAndreyView Answer on Stackoverflow
Solution 12 - JavaAndreyView Answer on Stackoverflow