# What Is NaN: A Deeper Dive Into JavaScript's Implementation of the IEEE-754 Floating Point Standard

Updated on · 6 min read|`NaN`

, short for "Not a Number", is a special value in JavaScript and TypeScript (as well as many other programming languages) that represents an undefined or unrepresentable value resulting from an arithmetic operation. It is often used as a placeholder for a missing numerical value or as a way to signify an error.

However, what exactly is the type of `NaN`

in JavaScript? Is it a number, or is it a distinct data type? In this article, we will explore the intricacies of the `NaN`

data type, including its behavior in arithmetic operations, its relationship with other data types in JavaScript and beyond, and the results of the `typeof`

operator when applied to `NaN`

. We will also briefly discuss the usage of `NaN`

in TypeScript, as well as the built-in `Number.isNaN()`

and `isNaN()`

functions that can be used to test for the `NaN`

data type.

## NaN data type in JavaScript

When exploring the `NaN`

data type in JavaScript, you may encounter a seemingly peculiar behavior. By typing `typeof NaN`

into your browser console, the result displayed is `number`

. This may initially appear to be an odd quirk of the JavaScript programming language. However, it is actually a standard feature of all programming languages that implement The IEEE Standard for Floating-Point Arithmetic (IEEE 754).

TypeScript, for example, doesn't have a separate type to signify `NaN`

values, therefore this code is valid:

ts`let myNumber: number = NaN;`

ts`let myNumber: number = NaN;`

Moreover, TypeScript doesn't have a special mechanism to check for `NaN`

values. To check if a value is NaN in TypeScript, you can use the `Number.isNaN()`

or `isNaN()`

functions, discussed in more detail below.

ts`let myNumber: number = NaN; if (Number.isNaN(myNumber)) { console.log("myNumber is NaN"); } else { console.log("myNumber is not NaN"); }`

ts`let myNumber: number = NaN; if (Number.isNaN(myNumber)) { console.log("myNumber is NaN"); } else { console.log("myNumber is not NaN"); }`

In other programming languages, such as Ruby, the `NaN`

value can also be represented as an instance of either `Float`

or `BigDecimal`

. Therefore, the `NaN`

data type is not unique to JavaScript.

To further understand the `NaN`

concept in JavaScript, we can refer to the ECMA-262, 13th edition, which is the ECMAScript Language Specification. According to section 4.4.24, the `Number`

type is defined as a "*set of all possible Number values, including the special 'Not-a-Number' (NaN) value, positive infinity, and negative infinity.*" Subsequently, section 4.4.27 clarifies that `NaN`

is a "*number value that is an IEEE 754-2019 'Not-a-Number' value.*"

## What is the IEEE 754 standard?

First published in 1985, the primary goal of the IEEE 754 standard is to provide a consistent computational method using floating-point numbers across various processing environments, be it software, hardware, or a mix of both. Along with specifying formats and methods for floating-point arithmetic in computer programming environments, IEEE 754 also defines a set of special values. These special values include:

`0`

: Both`-0`

and`+0`

are distinct values, although they are equal. Here's an in-depth article explaining both zero values in JavaScript.- Denormalized number: A number that lies between the smallest normalized positive floating-point number and zero.
- Positive and negative
`Infinity`

: Values representing infinitely large positive or negative numbers. `NaN`

: A numeric data type that cannot be represented within the computing system.

IEEE 754 defines two types of `NaN`

- a quiet `NaN`

(`qNaN`

) and signaling `NaN`

(`sNaN`

). The primary difference between the two is that `sNaN`

will cause an exception when used in arithmetic operations, whereas `qNaN`

will not. In JavaScript, it appears that all `NaN`

values are quiet.

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

shell`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`

shell`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`

Most of the bits in the `NaN`

encoding are not used to store meaningful information, which means they can be manipulated to store actual data - this is known as NaN-tagging or NaN-boxing. By using NaN-tagging, programmers can add additional type information to values without having to create new data types or use external metadata.

## Testing for NaN values: Number.isNaN() vs isNaN()

JavaScript doesn't have a single `NaN`

value, in fact, according to ECMA-262, there are "*18,437,736,874,454,810,627 (that is, 2 ^{64} - 2^{53} + 3) values, representing the double-precision 64-bit format IEEE 754-2019 values as specified in the IEEE Standard for Binary Floating-Point Arithmetic, except that the 9,007,199,254,740,990 (that is, 2^{53} - 2) distinct 'Not-a-Number' values of the IEEE Standard are 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-defined; to ECMAScript code, all NaN values are indistinguishable from each other.*"

Since `NaN`

does not equal itself (in some programming languages, self-comparison is a widely used approach to test for NaNs), we need to use special methods such as `Number.isNaN()`

or `isNaN()`

to detect them.

It should be noted, that same-value equality methods, e.g. Object.is or
same-value-zero equality methods, e.g. the ones used by `Map`

and `Set`

for comparing key equality, determine whether two values are functionally identical in all contexts. These methods will produce `true`

when comparing `NaN`

to itself.

If you're interested in learning more about how to use `Set`

, in particular to remove duplicated items from an array, you might find this article helpful: Removing Duplicates with Map In JavaScript.

While both methods serve this purpose, they differ in their approach. `Number.isNaN()`

is more precise, as it only returns true if the value is currently `NaN`

and of the `number`

type. On the other hand, `isNaN()`

returns `true`

if the value is currently `NaN`

or if it **will become NaN after being coerced to a numeric value**. This distinction can lead to some unexpected results when using `isNaN()`

, as it may return `true`

for non-number values that are coerced to `NaN`

. In TypeScript, calling `isNaN()`

with an argument that is not of type `number`

will result in a type error, alerting the programmer to the potential issue. As a result, when testing for `NaN`

values, it is generally recommended to use `Number.isNaN()`

for its higher accuracy and stricter type checking.

To better illustrate the differences between these testing methods, here's a table comparing the output of `Number.isNaN()`

, `isNaN()`

, and `typeof value === "number"`

for various types of values.

Input value | Number.isNaN(value) | isNaN(value) | typeof value === "number" |
---|---|---|---|

NaN | true | true | true |

undefined | false | true | false |

null | false | false | false |

true | false | false | false |

"123" | false | false | false |

123 | false | false | true |

[] | false | false | false |

{} | false | true | false |

MDN provides a helpful explanation about testing against NaN.

## Conclusion

`NaN`

, or "Not a Number," is a special value found in JavaScript and many other programming languages. It represents undefined or unrepresentable values resulting from arithmetic operations. Although it may seem counterintuitive for `NaN`

to be considered a number, it is actually a result of the widely adopted IEEE 754 standard for floating-point arithmetic.

Understanding the behavior and type of `NaN`

in JavaScript is important for developers working with numeric operations. To detect `NaN`

values, developers can use methods such as `Number.isNaN()`

and `isNaN()`

. These methods help ensure the accuracy and reliability of numeric operations in JavaScript.