222

Just out of curiosity.

It doesn't seem very logical that typeof NaN is number. Just like NaN === NaN or NaN == NaN returning false, by the way. Is this one of the peculiarities of JavaScript, or would there be a reason for this?

Edit: thanks for your answers. It's not an easy thing to get ones head around though. Reading answers and the wiki I understood more, but still, a sentence like

A comparison with a NaN always returns an unordered result even when comparing with itself. The comparison predicates are either signaling or non-signaling, the signaling versions signal an invalid exception for such comparisons. The equality and inequality predicates are non-signaling so x = x returning false can be used to test if x is a quiet NaN.

just keeps my head spinning. If someone can translate this in human (as opposed to, say, mathematician) readable language, I would be grateful.

[addendum 2023/06] I've create a small module for checking the type of anything in ES. It may be helpful, check it @GitHub

KooiInc
  • 119,216
  • 31
  • 141
  • 177
  • 33
    +1: "NaN is a number but is not-a-number. Hum... what ?!" – ereOn May 10 '10 at 09:35
  • 17
    For extra fun; (NaN !== NaN) == true – Alex K. May 10 '10 at 09:37
  • 1
    Even more fun (but understandable coming to think of it, isNaN returns a boolean): isNaN(parseInt('nodice')) === isNaN(parseInt('someOtherNaN')) === true; – KooiInc May 10 '10 at 09:48
  • parseInt("1A") is 1 but the string itself isNaN - what is the string you are parsing? – mplungjan Jul 13 '11 at 12:12
  • 1
    If using jQuery, I prefer `isNumeric` over checking the type: `$.isNumeric(NaN);` returns false, where as `$.type(NaN);`, returns number. http://api.jquery.com/jQuery.isNumeric/ – Justin Jul 19 '13 at 18:56
  • My code wasn't working - stepping into debugger - and yes... ```typeof NaN``` is ```"number"``` *(need to add extra condition)* – Mars Robertson Mar 03 '16 at 23:07
  • 4
    As professional mathematician I must say that sentence has little in common with precise language of maths. – Dmitri Zaitsev May 29 '16 at 18:13
  • I hate to say it, but these nonsensical anomalies (which are more common than you'd want to believe) are among many reasons why the Javascript language is an utter dumpster fire. But, what can you expect from a language where you have to plaster 'use strict' over every file to get any sort of language-level code quality enforcement?. – java-addict301 Sep 02 '21 at 03:49
  • What else colud be? if you're not human, that's also a condition of a human...being ...not-a-human??? I'm sorry – Ron Jun 21 '22 at 02:49
  • @Ron So: *Not a Number equals Number* is what you say? – KooiInc Jun 21 '22 at 08:51
  • Yhea the Not a Number being a number is really a nice funny Joke xD I would suggest to use the term Unknown Number instead – Lenny Aug 31 '23 at 09:11

22 Answers22

135

Well, it may seem a little strange that something called "not a number" is considered a number, but NaN is still a numeric type, despite that fact :-)

NaN just means the specific value cannot be represented within the limitations of the numeric type (although that could be said for all numbers that have to be rounded to fit, but NaN is a special case).

A specific NaN is not considered equal to another NaN because they may be different values. However, NaN is still a number type, just like 2718 or 31415.


As to your updated question to explain in layman's terms:

A comparison with a NaN always returns an unordered result even when comparing with itself. The comparison predicates are either signalling or non-signalling, the signalling versions signal an invalid exception for such comparisons. The equality and inequality predicates are non-signalling so x = x returning false can be used to test if x is a quiet NaN.

All this means is (broken down into parts):

A comparison with a NaN always returns an unordered result even when comparing with itself.

Basically, a NaN is not equal to any other number, including another NaN, and even including itself.

The comparison predicates are either signalling or non-signalling, the signalling versions signal an invalid exception for such comparisons.

Attempting to do comparison (less than, greater than, and so on) operations between a NaN and another number can either result in an exception being thrown (signalling) or just getting false as the result (non-signalling or quiet).

The equality and inequality predicates are non-signalling so x = x returning false can be used to test if x is a quiet NaN.

Tests for equality (equal to, not equal to) are never signalling so using them will not cause an exception. If you have a regular number x, then x == x will always be true. If x is a NaN, then x == x will always be false. It's giving you a way to detect NaN easily (quietly).

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953
  • 4
    good explanation, although I disagree in the last two sentences: a better way to check if x is a NaN is using isNaN() function – Carlos Morales Aug 09 '13 at 13:50
  • 1
    @DominicRodger here's how I think about it: `typeof a === 'number'` means "a is stored internally as an IEEE 754 float" – Andy Sep 01 '15 at 16:47
  • Why does `Infinity === Infinity` return `true` if an `Infinity` can be produced by different values: 1.0 / 0.0 or 2.0 / 0.0? – Hashem Qolami May 22 '16 at 09:15
  • 1
    @Hashem, quite likely because they're considered the same infinity. Treating division as repeated subtraction, it makes no difference whether you start at two or one, it's the same number of steps required to reach (or, more accurately, *not* reach) zero. I understand math gurus do *have* different classes of infinity but (1) I suspect `1/0` and `2/0` lay in the same class and (2) there's only one class of infinity in IEEE754 (other than `+/-` of course). – paxdiablo May 22 '16 at 11:02
  • What is "unordered result"? – Dmitri Zaitsev May 29 '16 at 18:27
  • Actually the comparison `NaN < 0` evaluates to `false`! – Dmitri Zaitsev May 29 '16 at 18:29
  • @DmitriZaitsev: as per a C11 footnote, `IEC 60559 requires that the built-in relational operators raise the ‘‘invalid’’ floating-point exception if the operands compare unordered, as an error indicator for programs written without consideration of NaNs; the result in these cases is false.` I've also changed the erroneous statement in the answer re returning NaN - thanks for the heads-up, I can only assume I was drunk at the time I wrote that :-) – paxdiablo May 30 '16 at 03:01
  • No worries, the design is so horribly confusing and inconsistent, no wonder. – Dmitri Zaitsev May 30 '16 at 12:19
  • "A specific NaN is not considered equal to another NaN because they may be different values" --- this very common "explanation" actually has no merit as there is no other value than 'NaN'. – Dmitri Zaitsev May 30 '16 at 12:23
  • @DmitriZaitsev, I suspect you're misreading my explanation. There may well only be one NaN in the IEEE754 encoding scheme. However, there are an *infinite* number of *actual* numbers that NaN can refer to and it was these values I was referring to. For example, the square root of `-1`, the natural logarithm of `-42`, and `0 / 0` are *distinct* numbers in math, but will all appear as `NaN` in IEEE754. – paxdiablo May 30 '16 at 13:47
  • 1
    I am not aware of any way to define these exceptional "actual numbers" in any meaningful way. In maths the log and the root of negatives can only be obtained by means of extension of reals to complex numbers, where they evaluate to multiple values, and `0/0` is not defined in any meaningful way, other than saying its "value" is the whole set of numbers. And even if they were defined, `Math.log(-1) == Math.log(-1)` still evaluates to `false`. So not only there are no "actual numbers" other than `NaN` but even if there were, they were not used for comparison. – Dmitri Zaitsev May 31 '16 at 13:05
  • So why is **"two" * 2** of type number? it returns NaN, surely this can never represent a numberical number like in the above example – SuperUberDuper Feb 06 '17 at 22:43
  • @SuperUberDuper, it's probably to do with the preferred type of the arguments given to the multiplication operator. ECMAScript states when applying `ToNumber` to a string, "If the grammar cannot interpret the string as an expansion of StringNumericLiteral, then the result of ToNumber is NaN." So, once `"two"` has been converted to `NaN` because of that, the multiplication rules in the standard take over: "If either operand is NaN, the result is NaN." – paxdiablo Feb 07 '17 at 04:49
  • that really doesn't make sense at all, despite the background, it's just wrong – Mladen Janjetovic May 24 '17 at 13:13
  • @MladenJanjetovic, not sure which bit you're claiming to be wrong (or whether it just *seems* wrong to you). If it's something in the answer, please let me know so I can fix or explain. If it's the behaviour of ECMAScript as per SuperUberDuper's comment, well, that's just lost in the general mish-mash of "all things wrong with ECMAScript" :-) – paxdiablo May 24 '17 at 13:25
  • @paxdiablo Just wrong in general :) it just passes the scope of programming and common sense. The answer is great ;) – Mladen Janjetovic May 24 '17 at 13:34
69

It means Not a Number. It is not a peculiarity of javascript but common computer science principle.

From http://en.wikipedia.org/wiki/NaN:

There are three kinds of operation which return NaN:

Operations with a NaN as at least one operand

Indeterminate forms

  • The divisions 0/0, ∞/∞, ∞/−∞, −∞/∞, and −∞/−∞
  • The multiplications 0×∞ and 0×−∞
  • The power 1^∞
  • The additions ∞ + (−∞), (−∞) + ∞ and equivalent subtractions.

Real operations with complex results:

  • The square root of a negative number
  • The logarithm of a negative number
  • The tangent of an odd multiple of 90 degrees (or π/2 radians)
  • The inverse sine or cosine of a number which is less than −1 or greater than +1.

All these values may not be the same. A simple test for a NaN is to test value == value is false.

Charles Beattie
  • 5,739
  • 1
  • 29
  • 32
22

The ECMAScript (JavaScript) standard specifies that Numbers are IEEE 754 floats, which include NaN as a possible value.

ECMA 262 5e Section 4.3.19: Number value

primitive value corresponding to a double-precision 64-bit binary format IEEE 754 value.

ECMA 262 5e Section 4.3.23: NaN

Number value that is a IEEE 754 "Not-a-Number" value.

IEEE 754 on Wikipedia

The IEEE Standard for Floating-Point Arithmetic is a technical standard established by the Institute of Electrical and Electronics Engineers and the most widely used standard for floating-point computation [...]

The standard defines

  • arithmetic formats: sets of binary and decimal floating-point data, which consist of finite numbers (including signed zeros and subnormal numbers), infinities, and special "not a number" values (NaNs)

[...]

SparK
  • 5,181
  • 2
  • 23
  • 32
Jeremy
  • 1
  • 85
  • 340
  • 366
9

typeof NaN returns 'number' because:

  • ECMAScript spec says the Number type includes NaN:

    4.3.20 Number type

    set of all possible Number values including the special “Not-a-Number” (NaN) values, positive infinity, and negative infinity

  • So typeof returns accordingly:

    11.4.3 The typeof Operator

    The production UnaryExpression : typeof UnaryExpression is evaluated as follows:

    1. Let val be the result of evaluating UnaryExpression.
    2. If Type(val) is Reference, then
      1. If IsUnresolvableReference(val) is true, return "undefined".
      2. Let val be GetValue(val).
    3. Return a String determined by Type(val) according to Table 20.

                    Table 20 — typeof Operator Results
    ==================================================================
    |        Type of val         |              Result               |
    ==================================================================
    | Undefined                  | "undefined"                       |
    |----------------------------------------------------------------|
    | Null                       | "object"                          |
    |----------------------------------------------------------------|
    | Boolean                    | "boolean"                         |
    |----------------------------------------------------------------|
    | Number                     | "number"                          |
    |----------------------------------------------------------------|
    | String                     | "string"                          |
    |----------------------------------------------------------------|
    | Object (native and does    | "object"                          |
    | not implement [[Call]])    |                                   |
    |----------------------------------------------------------------|
    | Object (native or host and | "function"                        |
    | does implement [[Call]])   |                                   |
    |----------------------------------------------------------------|
    | Object (host and does not  | Implementation-defined except may |
    | implement [[Call]])        | not be "undefined", "boolean",    |
    |                            | "number", or "string".            |
    ------------------------------------------------------------------
    

This behavior is in accordance with IEEE Standard for Floating-Point Arithmetic (IEEE 754):

4.3.19 Number value

primitive value corresponding to a double-precision 64-bit binary format IEEE 754 value

4.3.23 NaN

number value that is a IEEE 754 “Not-a-Number” value

8.5 The Number Type

The Number type has exactly 18437736874454810627 (that is, 253−264+3) values, representing the double-precision 64-bit format IEEE 754 values as specified in the IEEE Standard for Binary Floating-Point Arithmetic, except that the 9007199254740990 (that is, 253−2) distinct “Not-a-Number” values of the IEEE Standard are represented in ECMAScript as a single special NaN value. (Note that the NaN value is produced by the program expression NaN.)

Oriol
  • 274,082
  • 63
  • 437
  • 513
6

NaN != NaN because they are not necessary the SAME non-number. Thus it makes a lot of sense... Also why floats have both +0.00 and -0.00 that are not the same. Rounding may do that they are actually not zero.

As for typeof, that depends on the language. And most languages will say that NaN is a float, double or number depending on how they classify it... I know of no languages that will say this is an unknown type or null.

Dave
  • 10,748
  • 3
  • 43
  • 54
Cine
  • 4,255
  • 26
  • 46
  • 1
    ehr, consider: var x = parseInt('no dice'), y = x; Now I would say that both NaN's are exactly the same? But no, x === y returns false too. – KooiInc May 10 '10 at 09:38
  • yes, but you cant be SURE, and thus they are not the same. It is the same logic as NULLable logic in database. Although many people think of them as the same as null pointers from other programming languages, they infact have a totally different semantics. They are "UNKNOWN" and thus one NULL value compared to another is always false. Doing calculations on a NULL value ends up with the result NULL. Try to view it from the perspective of the value being called UNKNOWN instead – Cine May 11 '10 at 01:39
  • As being of type `number`, `NaN` is primitive, and hence uniquely determined by its value. – Dmitri Zaitsev May 17 '16 at 03:45
5

NaN is a valid floating point value (http://en.wikipedia.org/wiki/NaN)

and NaN === NaN is false because they're not necessarily the same non-number

Charles Ma
  • 47,141
  • 22
  • 87
  • 101
  • 1
    Sorry but I have to say that's not a good way to think about it. "not necessarily the same non-number" does not mean they are *always* different and comparing them should yield false. It's best not to quantify NaN and just think of it as an oddity in our knowledge base. – Dave Dec 10 '11 at 03:13
  • 1
    So why all `Infinity`s somehow are identical? Any thoughts? – Hashem Qolami May 22 '16 at 09:17
4

NaN stands for Not a Number. It is a value of numeric data types (usually floating point types, but not always) that represents the result of an invalid operation such as dividing by zero.

Although its names says that it's not a number, the data type used to hold it is a numeric type. So in JavaScript, asking for the datatype of NaN will return number (as alert(typeof(NaN)) clearly demonstrates).

Joachim Sauer
  • 302,674
  • 57
  • 556
  • 614
3

A better name for NaN, describing its meaning more precisely and less confusingly, would be a numerical exception. It is really another kind of exception object disguised as having primitive type (by the language design), where at the same it is not treated as primitive in its false self-comparison. Whence the confusion. And as long as the language "will not make its mind" to choose between proper exception object and primitive numeral, the confusion will stay.

The infamous non-equality of NaN to itself, both == and === is a manifestation of the confusing design forcing this exception object into being a primitive type. This breaks the fundamental principle that a primitive is uniquely determined by its value. If NaN is preferred to be seen as exception (of which there can be different kinds), then it should not be "sold" as primitive. And if it is wanted to be primitive, that principle must hold. As long as it is broken, as we have in JavaScript, and we can't really decide between the two, the confusion leading to unnecessary cognitive load for everyone involved will remain. Which, however, is really easy to fix by simply making the choice between the two:

  • either make NaN a special exception object containing the useful information about how the exception arose, as opposed to throwing that information away as what is currently implemented, leading to harder-to-debug code;
  • or make NaN an entity of the primitive type number (that could be less confusingly called "numeric"), in which case it should be equal to itself and cannot contain any other information; the latter is clearly an inferior choice.

The only conceivable advantage of forcing NaN into number type is being able to throw it back into any numerical expression. Which, however, makes it brittle choice, because the result of any numerical expression containing NaN will either be NaN, or leading to unpredictable results such as NaN < 0 evaluating to false, i.e. returning boolean instead of keeping the exception.

And even if "things are the way they are", nothing prevents us from making that clear distinction for ourselves, to help make our code more predictable and easierly debuggable. In practice, that means identifying those exceptions and dealing with them as exceptions. Which, unfortunately, means more code but hopefully will be mitigated by tools such as TypeScript of Flowtype.

And then we have the messy quiet vs noisy aka signalling NaN distinction. Which really is about how exceptions are handled, not the exceptions themselves, and nothing different from other exceptions.

Similarly, Infinity and +Infinity are elements of numeric type arising in the extension of the real line but they are not real numbers. Mathematically, they can be represented by sequences of real numbers converging to either + or -Infinity.

Dmitri Zaitsev
  • 13,548
  • 11
  • 76
  • 110
2

Javascript uses NaN to represent anything it encounters that can't be represented any other way by its specifications. It does not mean it is not a number. It's just the easiest way to describe the encounter. NaN means that it or an object that refers to it could not be represented in any other way by javascript. For all practical purposes, it is 'unknown'. Being 'unknown' it cannot tell you what it is nor even if it is itself. It is not even the object it is assigned to. It can only tell you what it is not, and not-ness or nothingness can only be described mathematically in a programming language. Since mathematics is about numbers, javascript represents nothingness as NaN. That doesn't mean it's not a number. It means we can't read it any other way that makes sense. That's why it can't even equal itself. Because it doesn't.

Louis
  • 21
  • 1
1

If using jQuery, I prefer isNumeric over checking the type:

console.log($.isNumeric(NaN));  // returns false
console.log($.type(NaN));       // returns number

http://api.jquery.com/jQuery.isNumeric/

Justin
  • 26,443
  • 16
  • 111
  • 128
  • Thanks man. I had problems with `isNumber` from `util` package of Typescript. Good that we still use `jQuery` in our project so used your suggestion instead. – Ashok M A Nov 16 '17 at 14:12
  • For the rec, `isNumber` from `util` of typescript also returns `true` for `NaN`. – Ashok M A Nov 16 '17 at 14:13
1

This is simply because NaN is a property of the Number object in JS, It has nothing to do with it being a number.

Dominic Rodger
  • 97,747
  • 36
  • 197
  • 212
Nullw0rm
  • 913
  • 1
  • 6
  • 13
  • Like every other object, Number can have any type of property. `Number.fu = "bar"; alert(typeof Number.fu);` – Alsciende May 10 '10 at 14:10
  • `NaN` is not the value stored in `Number.NaN`, whatever it might be. `NaN` is a primitive value of Number type. And additionally, the value of `Number.NaN` is `NaN`, but that's unrelated. – Oriol Jan 10 '15 at 21:06
1

The best way to think of NAN is that its not a known number. Thats why NAN != NAN because each NAN value represents some unique unknown number. NANs are necessary because floating point numbers have a limited range of values. In some cases rounding occurs where the lower bits are lost which leads to what appears to be nonsense like 1.0/11*11 != 1.0. Really large values which are greater are NANs with infinity being a perfect example.

Given we only have ten fingers any attempt to show values greater than 10 are impossible, which means such values must be NANs because we have lost the true value of this greater than 10 value. The same is true of floating point values, where the value exceeds the limits of what can be held in a float.

mP.
  • 18,002
  • 10
  • 71
  • 105
  • Infinity is not represented by a NaN. Attempting to represent a number outside of the range would be rounded down (to max/-inf) or up (to min/+inf). – OrangeDog Apr 15 '14 at 09:25
1

NaN is still a numeric type, but it represents value that could not represent a valid number.

Matthew Abbott
  • 60,571
  • 9
  • 104
  • 129
1

Because NaN is a numeric data type.

BenM
  • 52,573
  • 26
  • 113
  • 168
1

NaN is a number from a type point of view, but is not a normal number like 1, 2 or 329131. The name "Not A Number" refers to the fact that the value represented is special and is about the IEEE format spec domain, not javascript language domain.

6502
  • 112,025
  • 15
  • 165
  • 265
0

Javascript has only one numeric data type, which is the standard 64-bit double-precision float. Everything is a double. NaN is a special value of double, but it's a double nonetheless.

All that parseInt does is to "cast" your string into a numeric data type, so the result is always "number"; only if the original string wasn't parseable, its value will be NaN.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
0

We could argue that NaN is a special case object. In this case, NaN's object represents a number that makes no mathematical sense. There are some other special case objects in math like INFINITE and so on.

You can still do some calculations with it, but that will yield strange behaviours.

More info here: http://www.concentric.net/~ttwang/tech/javafloat.htm (java based, not javascript)

Pedro Loureiro
  • 11,436
  • 2
  • 31
  • 37
0

You've got to love Javascript. It has some interesting little quirks.

http://wtfjs.com/page/13

Most of those quirks can be explained if you stop to work them out logically, or if you know a bit about number theory, but nevertheless they can still catch you out if you don't know about them.

By the way, I recommend reading the rest of http://wtfjs.com/ -- there's a lot more interesting quirks than this one to be found!

Spudley
  • 166,037
  • 39
  • 233
  • 307
0

The value NaN is really the Number.NaN hence when you ask if it is a number it will say yes. You did the correct thing by using the isNaN() call.

For information, NaN can also be returned by operations on Numbers that are not defined like divisions by zero or square root of a negative number.

Rob
  • 2,618
  • 2
  • 22
  • 29
  • In what sense it is "the value"? `NaN == Number.NaN` evaluates to `false`! – Dmitri Zaitsev May 17 '16 at 03:47
  • @DmitriZaitsev Have you read the thread? And have you tried if (parseInt("nan") == Number.NaN)? Also try != and see what it tells you. – Rob May 17 '16 at 13:58
  • Sorry, forgot the stupid `NaN==NaN` being `false`, it must have been a sadist who invented that to make everyone suffer. – Dmitri Zaitsev May 17 '16 at 14:53
0

Everything is very simple, just check the NaN constructor function and it will be Number constructor function:

NaN.__proto__
  • You might want to add more context around how the constructor function understanding helps when OP has given various examples of how they are unable to grasp the concept with NaN === NaN and NaN == NaN – Harman Aug 12 '23 at 03:42
  • 1
    Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Harman Aug 12 '23 at 03:42
-2

An example

Imagine We are converting a string to a number:

Number("string"); // returns NaN

We changed the data type to number but its value is not a number!

Amir Fo
  • 5,163
  • 1
  • 43
  • 51
-2

It is special value of Number type as POSITIVE_INFINITY

Why? By design

RiaD
  • 46,822
  • 11
  • 79
  • 123