For the second time today I noticed someone on twitter berating javascript over this little connundrum:

> NaN == NaN
false
> NaN === NaN
false
> NaN !== NaN
true
>

Counterintuitively, it would seem that NaN does not equal NaN. But let’s think about this for a second. Is it really that strange or just a symptom of what the logical symbol NaN actually stands for?

Thing is, NaN stands for “Not a Number” and if memory serves comes right out of IEEE754 floating point arithmetic. It’s very handy for representing things like 0/0, different kinds of infinity and operations involving infinities. In short, it represents an undefinable number.

Now, what could possibly be the result of comparing two undefinable numbers?

Mathematically, I have no idea what the result should be … probably something we simply agreed upon? Like how the 0th power is 1. But in my naive understanding of these things it should produce random results. However, JavaScript is kind enough to always claim that NaN does not equal NaN, if for naught else than to remind us we are trying to do something stupid.

Can anyone tell me if other languages handle this differently? Just produce an error of some sort?

Also, please share this post with your local JavaScript newbie, I die a little every time I see that sort of tweet.

Enhanced by Zemanta
  • http://www.kamilkisiel.net Kamil Kisiel

    This isn’t a language thing, according to the standard any comparison with NaN should return False. According to http://stackoverflow.com/questions/558267/equality-with-double-nan C# even implements IsNaN(v) as v != v.

  • c0de

    0th power is not agreed upon, it is actually derived from the n^0 = x, taking the logarithm of both sides would give you log(n^0) = log(x), which after using the property that log(n^0) = 0*log(n) = 0, gives you: 0 = log(x), which is only true for x being 1, therefore you have the proof that for any n, zeroth power is = 1.

    On the other hand, comparing undefined numbers is undefined. Just as you can’t do inf + inf or inf-inf, you can’t compare infinities nor you can compare anything that is undefined.

    Cheers

  • c0de

    Of course n > 0, x > 0, for n and x being real, having the domain of the logarithmic function in mind

  • Sebastian

    Think about 0/0, it’s not equal to 0/0 as well because equality concept is pointless in this case. Wikipedia explains it quite well http://en.wikipedia.org/wiki/NaN

  • Anonymous

    I thought the definition of NaN was “the numeric-type value that is not equal to anything, including NaN”

  • Guest

    It’s not a language thing - IEEE standards for floating point math require this behavior, so all compliant environments behave this way.

    For more fun, investigate why Inf sometimes equals Inf, and sometimes not…

  • Eternal

    While that prof is true, it’s not applicable to the full set used in computing (integers, floats etc) meaning that you have to chose what to do when the case where that profs not applicable occurs.

    That is  0^0 is chosen to be 1.

  • Anonymous

    FWIW:

    [nathanb@nathanb-box ~/src/_sandbox] cat nantest.c
    #include
    #include

    int
    main(int argc, char** argv)
    {
            double d;

            d = sqrt(-1);

            printf(“%f, %dn”, d, d == NAN);

            return 0;
    }

    [nathanb@nathanb-box ~/src/_sandbox] gcc -o nan -lm nantest.c
    [nathanb@nathanb-box ~/src/_sandbox] ./nan
    nan, 0

  • c0de

    Agreed.

  • Matthew

    It has long been an established philosophical question: Should a null == null? For example, in a survey stored in a database, a null might mean “didn’t answer”, “found question offensive”, “does not apply” or “died of heart attack half way through survey”. Each of these might have serious implications to the survey’s results – and taking offence is not the same as the question not applying.

    It is more correct for every null to respond to an isNull method than for two nulls from two different sources providing a meaning-heavy answer (maybe null == null should return null?)

    So to answer the NaN question, where we have essentially two numerical nulls resulting from impossible questions being asked, a comparison should really ask “Were these two results gleaned from the same impossible equation?” At that point, you have several difficult questions – should 10 * “love” == 10 * “hate”? Should x^2 + 2x + (1*”monkey”) == (x + 1*”monkey”)*(x + 1*”monkey”)?

    It’s a ludicrous question. If you have the choice, I vote the answer should be null or an exception raised. If the language dictates that only true or false are valid responses, then false is the only reasonable answer. If the programmer doesn’t care, (10 * “fish”).toString() == (10 * “fish”).toString()

  • Matthew

    Sorry, clearly my maths head isn’t on.

    (x + 1*”monkey”)*(x + 1*”monkey”) should == x^2 + 2x + “monkey”^2

    where I’m using a ^ b as shorthand for Math.pow(a, b)

    What was I thinking?

  • http://recursive.myopenid.com/ tom

    C# handles it the same way.  double.NaN != double.NaN

  • Brian Hurt

    IEEE 754 floating point spec, which is implemented in hardware by everyone (pretty much) these days, specifies NaN != NaN.  And this makes perfect sense.  Consider: sqrt(-1) = NaN.  So does sqrt(-2).  So are you claiming that sqrt(-1) = sqrt(-2)?  If you demand NaN = NaN, then you are.  NaN means Not a Number.  It’s an error condition, not a value.

    There is a difference between ordering (where NaN = NaN makes sense) and numeric equality/comparison (where NaN = NaN implies sqrt(-1) = sqrt(-2)). 

  • anon

    In R:
    > NaN==NaN[1] NA> NaN!=NaN[1] NA> is.nan(NaN==NaN)[1] FALSE> is.nan(NaN!=NaN)[1] FALSE

  • http://tristram.squarespace.com Tristram Brelstaff

    Here is a paper by Gary Leavens which discusses these problems:
      http://www.jot.fm/issues/issue_2006_03/column8/

  • Ff

    It’s logical. NaN represents results of a variety of operations (infinities, div by zero etc) and that information is lost when the result is represented just by NaN, so how can they evaluate to equal. Also NaN is a non-value so you can’t value compare it and except it to be equal to anything at all.

  • William Riley-Land

    Here’s something not being considered: which is most useful, that NaN === NaN or doesn’t?  They could’ve made a bad choice in the spec (possibly), although I find it hard to imagine depending on performing math with NaNs… in other words it always indicates an error state.  (Right?)I guess I want to know if there is any time that NaN !== NaN is actually useful.  In what situation would that help you to write good code, elegantly perform an algorithm, etc.?

  • JC

    Would that not be   x^2 + 2(x*”monkey”) + “monkey”^2   ? …  or perhaps x^2 + x*”monkey” + “monkey”*x + “monkey”^2    if  x and “monkey” do not commute.