What is the type of NaN?
Tags: javascript, nan, numbers
Published: 2019-08-22 20:43:12

_The article was originally posted on my [personal blog](https://claritydev.net/blog/what-is-the-type-of-nan)_.

I was recently answering an interesting [question](https://stackoverflow.com/q/57546335/4468021) on Stack Overflow about the type of `NaN`. 

{% stackoverflow 57546335 %}

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](https://en.wikipedia.org/wiki/IEEE_754) (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](https://www.ecma-international.org/ecma-262/10.0/index.html), the ECMAScript Language Specification, [section 4.3.21](https://www.ecma-international.org/ecma-262/10.0/index.html#sec-terms-and-definitions-number-type) 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](https://www.ecma-international.org/ecma-262/10.0/index.html#sec-terms-and-definitions-nan) 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](https://2ality.com/2012/03/signedzero.html) about both zero values in JS), [denormalised number](https://en.wikipedia.org/wiki/Denormal_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](https://www.ecma-international.org/ecma-262/10.0/index.html#sec-ecmascript-language-types-number-type), 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](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN#Testing_against_NaN) 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](https://mobile.twitter.com/Clarity_89).