

Javascript's NaN - beghbali
http://coderwall.com/p/sekogw

======
jensnockert
Yet another post that underestimates the importance on NaN, it isn't 'WTF' at
all if you understand its design. Sure, the naming in ES makes it a bit silly
since NaN is a number, but it is something you only have to see once to
understand.

Don't mess with IEEE 754, it is almost universally adopted for binary
floating-point for very good reasons.

~~~
elliptic
NaN is incredibly useful, but I'm not so sure that 1/"a" = NaN is a great
idea.

~~~
grayrest
Strings that arent numeric are type coerced into NaN. Using unary plus to
coerce to number: +"2" is the primitive number 2 while +"a" is NaN and per the
floating point spec, any arithmetic operation on NaN results in NaN.

The correct though unintuitive way to check for NaN is `(x === x) === false`.
NaN is a number per the IEEE 754.

The majority of Javascript WTFs are due to type coercion. Use triple equals
and check your inputs to avoid.

~~~
some-1
No, the correct way is to use the global function isNaN(x);

~~~
grayrest
isNaN will return true for NaN and all values that coerce to it. The equals
check will test ONLY for NaN itself:

var x = "a";

isNaN(x); // true

(x === x) === false // false

x = NaN

isNaN(x); // true

(x === x) === false // true

------
dap
Yes, it's goofy that typeof (NaN) == 'number'. But it's not that unreasonable
to have a numeric value that's explicitly invalid. Pointers and references in
other languages have null, which is a legal value for any type of object, but
is explicitly invalid if used as an object.

Also, isNaN is global.

~~~
SeanLuke
> Yes, it's goofy that typeof (NaN) == 'number'.

You should be harsher on him. NaN is definitely a number in practically every
programming language.

    
    
        (type-of (/ 0.0 0.0))
            SINGLE-FLOAT
    
        System.err.println((new Double(0.0/0.0)) instanceof Number)
            true
    
        from types import *
        type(1e10000 / 1e10000)
            <type 'float'>
    

It looks like the blogger is just out and out mistaken. But there's more. The
poster goes on about NaN not being easy to check for: not realizing that it's
the only value which is never equal to itself. He even thinks this is a bug.

------
beering
One wonders if this blog post would have been written at all if the author was
familiar with NaN in floating-point numbers and knew that isNaN was a thing.

isNaN is the defined method of checking if something Not A Number or can't be
converted into a number.

The Real WTF (and infamous "feature" of JS) is that many things can be
converted into a number.

    
    
        isNaN("string") => true
        isNaN({}) => true
    

but you might not expect that

    
    
        isNaN("3e2") => false
        isNaN("") => false
        isNaN([]) => false

~~~
mbrubeck
The "Harmony" proposal for the next JavaScript spec includes Number.isNaN,
which is meant to be a less-confusing version (with no type coercion). It's
currently implemented in Firefox Nightly builds: <http://bugzil.la/749818>

    
    
        Number.isNaN(NaN) => true
    
        Number.isNaN(3e2) => false
        Number.isNaN("NaN") => false
        Number.isNaN("string") => false
        Number.isNaN({}) => false
        Number.isNaN("3e2") => false
        Number.isNaN([]) => false
    

<http://wiki.ecmascript.org/doku.php?id=harmony:number.isnan>

------
dreish
This is hardly a JavaScript quirk. In Clojure:

    
    
        hackclj.core=> Double/NaN
        NaN
        hackclj.core=> (== Double/NaN Double/NaN)
        false
        hackclj.core=> (= Double/NaN Double/NaN) 
        false
        hackclj.core=> (.equals Double/NaN Double/NaN)
        true
        hackclj.core=> (identical? Double/NaN Double/NaN)
        false
        hackclj.core=> (type Double/NaN)
        java.lang.Double
        hackclj.core=> (number? Double/NaN)
        true
    

In Perl (which doesn't have a concept of a number type distinct from other
scalars such as strings, but we can see that it participates in addition
differently from non-numeric scalars, which behave like 0):

    
    
          DB<1> $inf = 1e300 * 1e300
        
          DB<2> $nan = $inf - $inf
        
          DB<3> print $nan
        nan
          DB<4> print ($nan == $nan)
        
          DB<5> print ref($nan)
        
          DB<6> print $nan+1   
        nan
    

In Ruby:

    
    
        irb(main):001:0> inf = 1e300*1e300
        => Infinity
        irb(main):002:0> nan = inf-inf
        => NaN
        irb(main):003:0> nan == nan
        => false
        irb(main):004:0> nan.class
        => Float
    

Python 2.7.3 (much earlier versions got equality wrong, claiming nan == nan):

    
    
        >>> inf = 1e300*1e300
        >>> nan = inf-inf
        >>> nan
        nan
        >>> nan == nan
        False
        >>> type(nan)
        <type 'float'>

------
tikhonj
Of all the things to complain about, he chose one that is _not_ JavaScript's
fault: the fact that NaN is a number and equality on NaN is not reflexive is a
property of the floating point number standard.

Try it in some other language you have lying around, like Python:

    
    
        >>> type(float('nan'))
        <type 'float'>
        >>> float('nan') == float('nan')
        False
    

Also Haskell:

    
    
        Prelude> 0/0
        NaN
        Prelude> 0/0 == 0/0
        False
    

If anything, it's refreshing that JavaScript _does_ behave like other
languages in this case!

------
simonster
The language-agnostic way to check for NaN is to check whether x != x. Some
languages might also need a type check, but AFAIK JS isn't one of them.

------
JeremyBanks
I wonder how many blog posts could have been avoided if Number had just been
named Float instead.

~~~
Skalman
I think "Number" is a better name than "Float". It's a _much_ more common word
which I immediately get a feeling for. That typeof NaN === 'number' really
makes sense for me, and I feel that most wouldn't need a long explanation to
get it either.

~~~
JeremyBanks
I actually do agree that Number is a better name -- particularly for a
language that's many people's first experience with programming these days. My
comment was a tad sarcastic.

Though if they're not calling them floats, maybe they could have also come up
with a better name for NaN. If they used, say, "ERR", it would be something
many people had seen before (from calculators) and we'd get to stop hearing
people bitch about "NotANumber is a number WTF".

(I suppose "they" in this case must be the hypothetical well-treated team that
didn't develop JavaScript instead of a frustrated Brendan Eich.)

