tags:

views:

3691

answers:

11

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?

+20  A: 

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

Filip Ekberg
Yep, That's it. The value of i is Jon Skeet.
Andrew Rollings
Yes, double i = Double.NaN
Jaime Soriano
I generally hate people who downvote for no reason... I was the first to say "Not a Number" but didnt think java could handle that, since it doesnt handle anything else cool.
Filip Ekberg
+1 for being first to say "Not a Number" =)
Zach Scrivena
A: 

The only thing I can think of is that someone has overridden the operator== to be something other than ==.

Update: Actually, that's a C++ explanation, not a Java one. Not being a Java programmer, I'm not even sure if operator overloading is possible in Java.

LeopardSkinPillBoxHat
The "riddle" is specific to the Java language, which does not allow operator overloading.
William Brendel
You can overload in java? Can't you? :O
Filip Ekberg
That would be a serious lack of a feature if you couldn't, but I don't know Java either
Ed Swangren
No, you can't overload operators. And that lack is a "feature", apparently. Something about "someone could override + to do something confusing like concatenating strings".
Adam Jaskiewicz
define: JavaDefinition of Java; Lacking features.
Filip Ekberg
You can overload methods, but not operators.
Bill the Lizard
The simplest explanation is that objects in Java are all references (except for primitives), so it makes sense that the == operator tests for reference equivalence, not value equivalence. Also, the designers wanted to keep things as simple as possible, to prevent careless mistakes among programmers.
William Brendel
The designers of Java purposely decided not to allow operator overloading because they felt it led to more problems than it solved.
Bill the Lizard
Well, NOT creating java in the first place would nave NOT created a ton of problems. So i guess this reason is not that of a valid one!
+76  A: 
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.

Zach Scrivena
OH so you CAN do "Not a Number"!
Filip Ekberg
IEEE754 specifies "Not a Number", "Positive Infinity", and "Negative infinity" as representable values.
Crashworks
Works in C++ too ;)
BigSandwich
Ditto for JavaScript; NaN != NaN
Ates Goral
its mathematically solid, why should one unreal number equal another? 5/0 != sqrt(-4)
CrazyJugglerDrummer
+9  A: 
float i = Float.NaN;
while(i == i) ;
System.out.println("Not infinite!");
Aaron Maenpaa
+8  A: 
double i = Double.NaN;

NaN is not equal to anything, including itself.

Bill the Lizard
A: 

Unless i is being changed inside the loop?

NJ
That ";" character marks the end of the loop. There's no code inside it.
paxdiablo
The condition is evaluated before the body of the loop, so even if it were being changed within the loop it would still be true, with the exception given in other solutions.
Ignacio Vazquez-Abrams
i could be changed from outside the loop concurrently
Steve Kuo
+2  A: 

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.

mP
It would be easier to think of it as exceptiolbut if I actually knew what an exceptiolbut was :-).
paxdiablo
+8  A: 

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.

Dmitriy Matveev
A: 

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.

Jonathan Leffler
+1  A: 

A common trick in these sort of questions it in the assumption you make that i is an int. Other common assumptions might be s is a String, x,y are a 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 expect 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 twelve of them :)

while(x != 0 && x == -x) { }
Peter Lawrey
A: 

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.

Hooked
Why not? You are doing exactly the same calculation on exactly the same data, both results will contain exactly the same error.
Loren Pechtel
I can't remember exactly where I read it, but depending on your machine/implementation, the sin(x) on one function call has a miniscule chance of equaling sin(x) of a different call. It has to do with the accuracy of floating point digits (something is special about the trig functions that makes them not return the same value twice).
Hooked
See my update. Arcsine "undoes" the sin of x, so they should be equal, but they are not.
Hooked
That's not the same thing. Like Loren said, you're performing the exact same operation on `x`, which should yield the exact same result with the exact same inaccuracy. Arcsin can't reverse the result of a sin with floating point numbers because the value passed to `asin()` is not going to be exactly accurate. Therefore, the result of `asin()` will be inaccurate, making `x == asin(sin(x))` false. Also, arcsin doesn't necessarily "undo" a sin operation—the sin function can give the same result for multiple values of x, which is why `asin()` only returns numbers between -π/2 and π/2.
htw
You're right, I must have misinterpreted the text I was reading. However, for the original question, my assertion does hold true, since pure math states x == arcsine(sin(x)). Note that I am not a big math buff, but am trying to improve myself, so take everything I say with a grain of salt.
Hooked
No worries. However, your assertion that pure math states that "x == arcsin(sin(x))" is incorrect: here's why. In math, sin/cos take angles and convert them to coordinates on the unit circle (which has a radius of 1). But here's the thing: any angle outside of the range 0-2π radians has an equivalent angle that is within 0-2π radians. (For example, 7π/3 = π/3, since 7π/3 is just one revolution of 2π radians plus another π/3 radians). This means that *you can get the same value of sin with more than one angle*.
htw
In other words, arcsin can't always "undo" the sin function because it's impossible for arcsin to know what the original angle was. For example, the sin of both π/2 and 5π/2 give 1. But what's arcsin(1)? It obviously can't give both back, right? Therefore, the result of arcsin must be restricted to a range of 2π radians, meaning that it can't actually undo the result of the sin function unless the original angle is between 0 and 2π, or in C's case, -π/2 and π/2. (Indeed, arcsin(sin(5π/2)) = π/2.) Anyways, that was a really long explanation, but I hope that helps clear up any misconceptions.
htw