*The article was originally posted on my personal blog*.

I was recently answering an interesting question on Stack Overflow about the type of `NaN`

.

this is what´s happening

`typeof Number.parseInt('processed')`

prints `'number'`

.

But if `Number.parseInt('processed')`

gives `NaN`

.

And indeed if you type in your browser console `typeof NaN === 'number'`

you'll get true. The comments to the answer made me realise that this is not another one of JavaScript quirks, but in fact a standard feature of all the programming languages that implement The IEEE Standard for Floating-Point Arithmetic (IEEE 754).

In Ruby, for example `NaN`

can be either an instance of `Float`

or `BigDecimal`

.

And indeed, if we look at the ECMA-262, 10th edition, the ECMAScript Language Specification, section 4.3.21 states that number type represents a "set of all possible Number values including the special “Not-a-Number” (NaN) value, positive infinity, and negative infinity". A few subsections below, section 4.3.24 clarifies that NaN is a "number value that is an IEEE 754-2008 “Not-a-Number” value".

##### So what is this IEEE 754 standard?

First published in 1985, its main purpose is to provide a computational method with floating point numbers, which would have the same results independent of the environment where the processing is done, be it software, hardware or a mix of both. Together with specifying formats and methods for floating-point arithmetic in computer programming environments, IEEE 754 also defines a set of special values: `0`

(`-0`

and `+0`

are distinct values, although they both are equal; here's an in-depth article about both zero values in JS), denormalised number, positive and negative `Infinity`

, and `NaN`

, which the standard describes as a numeric data type that cannot be represented within the computing system. In fact, IEEE 754 defines two types of `NaN`

- a quiet `NaN`

(`qNaN`

) and a signalling `NaN`

(`sNaN`

). The most important difference between the two is that `sNaN`

will cause an exception when used in arithmetic operations and `qNaN`

won't. It seems like in JavaScript all the `NaN`

s are quiet, at least I wasn't able to find any information to the contrary.

Additionally, the standard defines an interesting list of special operations and their results:

```
number ÷ Infinity = 0
number ÷ -Infinity = -0
±Infinity × ±Infinity = ±Infinity
±non zero number ÷ ±0 = ±Infinity
number × ±Infinity = ±Infinity
Infinity + Infinity = ±Infinity
Infinity – -Infinity = +Infinity
-Infinity – Infinity = Infinity
-Infinity + – Infinity = Infinity
±0 ÷ ±0 = NaN
±Infinity ÷ ±Infinity = NaN
±Infinity × 0 = NaN
NaN == NaN (also '===' in JS) //False
```

##### Testing for NaN values

JavaScript doesn't have a single `NaN`

value, in fact, according to ECMA-262, there are "9007199254740990 (that is, 253 - 2) distinct “Not-a-Number” values of the IEEE Standard [...] represented in ECMAScript as a single special NaN value. In some implementations, external code might be able to detect a difference between various Not-a-Number values, but such behaviour is implementation-dependent; to ECMAScript code, all NaN values are indistinguishable from each other."

Because `NaN`

doesn't equal to itself (and in fact in some programming languages self-comparison is a widely used approach to test for `NaN`

s), we need to use a special `Number.isNaN()`

or `isNaN()`

methods to detect `NaN`

s. The difference between the two is that `isNaN()`

returns `true`

if the value is currently `NaN`

or **it is going to be NaN after it's coerced to numeric value **and `Number.isNaN()`

only will return `true`

if the value is currently `NaN`

. Generally `Number.isNaN()`

is more accurate since it also checks if the type of value is number. MDN has a handy explanation about testing against NaN.

Having "Not a Number" value to be a type of number is quite illogical, maybe a better name would be "Not a Real Number" or something along those lines. In this case, however, it's not a strange behaviour in JavaScript, but a general programming principle.

Got any questions/comments or other kinds of feedback about this post? Let me know here in the comments or on Twitter.

## Top comments (6)

c/o "You Don't Know JS"

github.com/getify/You-Dont-Know-JS...

Despite the (condescending) name, the YDKJS series is actually really great.

did the interpreter work like this.

if (token[0] == 'NaN') return false;

return token[0] == token[1];

just kidding

Haha, well it's more like each NaN has a different value under the hood, so technically they're not equal to each other.

Fun fact: since most of the bits in NaN encoding aren't used to store any meaningful information, they can be manipulated to store actual data - payload. This is called NaN-tagging or NaN-boxing and is mostly used for adding additional type encodings to values. Here's one interesting article about it.

wow thank you, never thought about that

You are writing:

Following explanation helped me to accept fact that NaN is number type=):

Very interesting article. I never knew there was a difference between isNaN and Number.isNaN. Thanks for sharing!