News for hackers. Stuff that matters.
Re:NaN does not equal NaN by simonsarris on Tuesday September 27, 2011 @04:31PM (#3045082)
This is of course how it is supposed to work. It is useful to define NaN this way, as a simple test for NaN is (num == num) returning false.

While we're on the topic of NaN, I'd like to mention a lesson from my little book of JavaScript you should never do[1]: You should never use null in JavaScript for the value of a yet-to-determine number. Always use NaN.

Why? It will be easier to detect problems:

    var determineLater = NaN;
    var blah = 5;
    blah += determineLater;
blah is now NaN because (5 + NaN) is NaN. We want this because we want to know if there's been some kind of error in the making of blah

Better:

    var determineLater = null;
    var blah = 5;
    blah += determineLater;
blah is now 5 because (5 + null) is 5. We do not want this because it doesn't let us know that there's been an error (the error typically being that determineLater was - incorrectly - never determined!)

[1] not a real book, just a text file of mis-use cases.

Re:NaN does not equal NaN by teaspoon on Tuesday September 27, 2011 @04:51PM (#3045178)
blah is now NaN because (5 + NaN) is NaN. We want this because we want to know if there's been some kind of error in the making of blah

Commence countdown to frontpage submission "Float is a monad". I agree with your justification for 5 + NaN evaluating to NaN, but it would be even more useful if NaN == x (and every other operation on NaN) would evaluate to NaN as well. That's obviously not possible in statically typed languages, but it is in JS.

Re:NaN does not equal NaN by sid0 on Tuesday September 27, 2011 @05:51PM (#3045404)
Haha, "float is a monad" is the first thing that popped into my head when I read that.
Re:NaN does not equal NaN by brendoncrawford on Tuesday September 27, 2011 @05:45PM (#3045373)
> You should never use null in JavaScript for the value of a yet-to-determine number. Always use NaN.

Actually, it is more idiomatic to use undefined for this purpose rather than NaN...

    var determineLater; // undefined
    var blah = 5;
    blah += determineLater; // blah is now NaN
Re:NaN does not equal NaN by masklinn on Tuesday September 27, 2011 @04:35PM (#3045106)
You know what's a simple test for NaN? The isNaN built-in function...
Re:NaN does not equal NaN by simonsarris on Tuesday September 27, 2011 @04:45PM (#3045159)
Yes, but this is bigger than that. JavaScript doesn't define NaN, IEEE-754 defines NaN and JavaScript takes its definition from that. So it's IEEE-754 thinks num == num being false is a good test for NaN.

For the record, isNaN in JavaScript is also not necessarily the fastest way of doing it: http://jsperf.com/nantest

Re:NaN does not equal NaN by masklinn on Tuesday September 27, 2011 @04:52PM (#3045185)
> For the record, isNaN in JavaScript is also not necessarily the fastest way of doing it

Which will absolutely not matter in 100% of the cases after rounding. `isNaN` is simple (your original criteria) and clearly says what it's doing.

Re:NaN does not equal NaN by grandpa on Tuesday September 27, 2011 @06:23PM (#3045513)
It's things like this that make it hard to write optimizers where floating point is used. Many algebraic identities just don't apply: x == x can't be reduced to true, 0-x isn't the same as -x (it fails for +0), x<=y isn't the opposite of x>y (because of NaN), (a+b)+c isn't the same as a+(b+c), and you can't replace ac+bc with a*(b+c).

The paper "What Every Computer Scientist Should Know About Floating Point Arithmetic" is a good guide to the details.

Re:NaN does not equal NaN by sev on Tuesday September 27, 2011 @05:17PM (#3045271)
The most intuitive way to describe this for me is:

You've got 2 things, but you know nothing about them. Does the fact that you know nothing about them alone make them equal?

True, they have a commonality (you know nothing about them) but that's not enough to make them equal.

Re:NaN does not equal NaN by mturmon on Tuesday September 27, 2011 @06:05PM (#3045461)
Yes, and the creators of the concept were kind enough to embed this intuition into the name, just so you can't forget.

All you know is what it is NOT, not what it IS. So you can't tell if it's the same as anything else.

Re:NaN does not equal NaN by scott_s on Tuesday September 27, 2011 @04:23PM (#3045042)
Re:NaN does not equal NaN by reduxredacted on Tuesday September 27, 2011 @06:05PM (#3045454)
As a former SQL guy myself, this issue wasn't a surprise the first time I saw it.

In MSSQL (and I believe this is somewhat, though not always universal since Structured Query Language is somewhat, though rarely completely compatible between RDBMSs), NULL does not equal NULL (or anything else). In SQL terms, the idea is that it's different from "empty", it's a value with no definition---an unknown.

NaN seemed like it should work the same way. "Zed" is NaN, "Bob" is NaN, "Zed" / "Bob" is NaN. None of those are equal, they simply make no sense, so they're undefinable. (quick disclaimer: It's been a few years since I've had to actually deal with NaN in JavaScript, so if it's now possible to divide "Zed" by "Bob" in newer specs or strange implementations of JS, and not end up with NaN, feel free to correct me, I won't take it personally. I'm not writing from a position of authority on the subject).

In the land of "sort-of standard SQL", this is remedied by Field IS NULL. I can see the a similar utility in JavaScript's IsNaN. It's important to know when two things return values that the equivalent of "unknown", and not allow the unknown to equal the other unknown.

EDIT: changed "not rarely" to "rarely" in second paragraph.

Re:NaN does not equal NaN by ams6110 on Tuesday September 27, 2011 @09:00PM (#3045983)
In Oracle, the empty string ('') is null, though otherwise it works mostly as you describe.
Re:NaN does not equal NaN by nyellin on Tuesday September 27, 2011 @04:25PM (#3045052)
At least Javascript has isNaN().

Exercise: Try checking for NaN in C. Then read [1] and see if your method is cross platform like you thought

[1] http://stackoverflow.com/questions/570669/checking-if-a-doub...

Re:NaN does not equal NaN by seppo0010 on Tuesday September 27, 2011 @04:22PM (#3045037)
Like NULL in SQL...

    sqlite> SELECT 1=1;
    1
    sqlite> SELECT 1=0;
    0
    sqlite> SELECT NULL!=NULL;
    
    sqlite> SELECT NULL=NULL;
Re:NaN does not equal NaN by brendoncrawford on Tuesday September 27, 2011 @04:56PM (#3045195)
This is correct behaviour. You are supposed to use `isNaN()`, which makes perfect sense.

This is the same as SQL where `NULL IS NULL` is true, but `NULL = NULL` is not true.

Re:NaN does not equal NaN by blahedo on Tuesday September 27, 2011 @06:54PM (#3045609)
Even better: since SQL has a tri-valued logic (T, F, Unknown) it can assign "Unknown" as the result of a test against NULL. That means that `3 = NULL` is not true, but `3 != NULL` is also not true. If testing against NULL were merely false, then you'd have the bizarre result that

  val > 3
and

  not (val <= 3)
might return different results!

(I was just teaching this today in my DB class! Fun.)

Re:NaN does not equal NaN by eftpotrm on Tuesday September 27, 2011 @04:56PM (#3045196)
Well, yes, this is how it's supposed to work, the values being defined as unknown. SQL is the same with NULLs not matching each other.

Interestingly, this once bit me the other way round. I get so used to NaN/NULL not matching itself that it's a bit off the radar to test, yet I discovered that SAS' equivalent concept, missing, does match with itself. Which caused some head scratching to find!

Re:NaN does not equal NaN by Swizec on Tuesday September 27, 2011 @04:51PM (#3045181)
For the record, I do not think there is anything breathtakingly special about this. But it seems to elude a lot of people and I wish it didn't.
Re:NaN does not equal NaN by voidr on Tuesday September 27, 2011 @04:51PM (#3045179)
1/0 is not equal to 2/0, they are both errors but not the same.
Re:NaN does not equal NaN by cdavid on Tuesday September 27, 2011 @05:05PM (#3045225)
actually, they are both equal to infinity:

    #include <stdio.h>

    int main()
    {
	float a = 1. / 0;
	float b = 2. / 0;

 	printf("%f == %f ? %d\n", a, b, a == b);
        return 0;
    }
will print:

    inf == inf ? 1
Moreover:

    #include <stdio.h>

    int main()
    {
	float a = 0. / 0;
	float b = a;

 	printf("%f == %f ? %d\n", a, b, a == b);
        return 0;
    }

    nan == nan ? 0
So this is certainly surprising without knowing quite a bit already about floats, because it means = is not only not transitive but even not reflexive.
Re:NaN does not equal NaN by blinks on Tuesday September 27, 2011 @05:13PM (#3045259)
Actually, they're _not_ both equal to infinity, in the mathematical sense (which I believe you're discussing) -- X / 0 is undefined.

What's equal to infinity is the limit of 1 / x as x approaches 0, and that's only from the positive side. From the negative side, it's -infinity.

Re:NaN does not equal NaN by cdavid on Tuesday September 27, 2011 @05:40PM (#3045349)
Nobody is discussing about usual mathematical definitions: this is about the IEEE754 standard. In that context, x / 0 is defined (to positive infinity). I was pointing the error of the OP about the explanation about Nan != Nan.
Re:NaN does not equal NaN by ajross on Tuesday September 27, 2011 @06:34PM (#3045549)
Actually no. Just in case you were confused by cdavid's sample code: the concise explanation is that division by zero in IEEE floating point produces an infinity (there are two: positive and negative), not a NaN. Neither is necessarily an "error" in the sense of a runtime exception (the generation of which is programmable).
Re:NaN does not equal NaN by Newky on Tuesday September 27, 2011 @04:45PM (#3045158)
var x = NaN; console.log(typeof x); //"number"
Re:NaN does not equal NaN by code_duck on Tuesday September 27, 2011 @04:27PM (#3045067)
Yes, that's how it is supposed to work.
Re:NaN does not equal NaN by antihero on Tuesday September 27, 2011 @04:30PM (#3045076)
Unless of course you are Dr James Anderson ;)