
NaN does not equal NaN - Swizec
http://swizec.com/blog/nan-does-not-equal-nan/swizec/2517
======
simonsarris
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.

~~~
teaspoon
_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.

~~~
sid0
Haha, "float is a monad" is the first thing that popped into my head when I
read that.

------
sev
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.

~~~
mturmon
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.

------
scott_s
Relevant discussions: <http://news.ycombinator.com/item?id=2024778> and
<http://news.ycombinator.com/item?id=2599331>

------
reduxredacted
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.

~~~
ams6110
In Oracle, the empty string ('') is null, though otherwise it works mostly as
you describe.

------
nyellin
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...](http://stackoverflow.com/questions/570669/checking-if-a-double-or-
float-is-nan-in-c)

------
seppo0010
Like NULL in SQL...

    
    
        sqlite> SELECT 1=1;
        1
        sqlite> SELECT 1=0;
        0
        sqlite> SELECT NULL!=NULL;
        
        sqlite> SELECT NULL=NULL;

------
brendoncrawford
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.

~~~
blahedo
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.)

------
eftpotrm
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!

------
Swizec
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.

------
voidr
1/0 is not equal to 2/0, they are both errors but not the same.

~~~
cdavid
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.

~~~
blinks
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.

~~~
cdavid
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.

------
Newky
var x = NaN; console.log(typeof x); //"number"

------
code_duck
Yes, that's how it is supposed to work.

------
antihero
Unless of course you are Dr James Anderson ;)

