Why JavaScript says that a number is not a number?

40,471

Solution 1

As I understand it, NaN is a sentinel instance of the Number class that represents, well, exactly what it stands for - numeric results that cannot be adequately represented. So 0/0 is not a number, in the sense that it's NaN, but it is a Number in terms of its type.

Perhaps it should have been called NaRN (Not a Representable Number).

Solution 2

If you have a variable and assign it the result of 0/0, the variable is still of numeric type, but the value is undefined (not a number). There are other conditions under which this can occur, but this illustrates what you are seeing.

Solution 3

You are confusing the type of your object with the value. NaN is a specific value that a an object of type number can be assigned with, for instance in the case of division of zero by zero or when trying to convert a number from a string that does not represent a number.

Solution 4

You should check out the Wikipedia article. It has more details.

Solution 5

Some definitions from W3Schools:

Infinity: A numeric value that represents positive/negative infinity

The POSITIVE_INFINITY property represents infinity, returned on overflow. NEGATIVE_INFINITY, represents negative infinity (returned on overflow).

The NaN property represents "Not-a-Number" value. This property indicates that a value is not a legal number.

The isFinite() function determines whether a number is a finite, legal number. This function returns false if the value is +infinity, -infinity, or NaN.

Some tests:

 var n1 = 1/0;
  var n2 = 0/0;
  var n3 = (Number.MAX_VALUE)*2; //overflow

  var b1 = Number.POSITIVE_INFINITY == n1;
  var b2 = Number.POSITIVE_INFINITY == n2;
  var b2n = Number.NEGATIVE_INFINITY == n2;
  var b3 = Number.POSITIVE_INFINITY == n3;

  var msg = "n1=" + n1 + ", n2=" + n2 + ", n3=" + n3;

  msg += "<br/> n1 Is POSITIVE_INFINITY=" + b1;
  msg += "<br/> n2 Is POSITIVE_INFINITY=" + b2;
  msg += "<br/> n2 Is POSITIVE_INFINITY=" + b2n;
  msg += "<br/> n3 Is POSITIVE_INFINITY=" + b3;

  msg += "<br/> n1 IsFinite=" + isFinite(n1);
  msg += "<br/> n2 IsFinite=" + isFinite(n2);
  msg += "<br/> n3 IsFinite=" + isFinite(n3);


  msg += "<br/> n1 + n1 =" + (n1 + n1) ;
  msg += "<br/> n1 - n1 =" + (n1 - n1) ;
  msg += "<br/> n2 + n1 =" + (n2 + n1) ;

  document.write(msg);

Shows

n1=Infinity, n2=NaN, n3=Infinity
n1 Is POSITIVE_INFINITY=true
n2 Is POSITIVE_INFINITY=false
n2 Is POSITIVE_INFINITY=false
n3 Is POSITIVE_INFINITY=true
n1 IsFinite=false
n2 IsFinite=false
n3 IsFinite=false
n1 + n1 =Infinity
n1 - n1 =NaN
n1 - n1 =NaN
Share:
40,471
Arseni Mourzenko
Author by

Arseni Mourzenko

Developer, architect, project manager, tester, and active DevOps supporter, I'm studying, observing and advising companies which have an important risk to fail their IT-related projects. I specialize in quality and productivity. After six years of freelancing, I worked for several companies, including Tata Con­sul­tan­cy Ser­vices. Today, I'm a happy member of Finaxys. I most­ly work with Lin­ux, Python, and Node.js, as well as the Mi­crosoft stack. Outside information technology, I'm interested by photography. I'm mostly active on SE.SE, and also maintain my blog. If you want to contact me, my email is [email protected]. Feel free to drop me a note about any de­vel­op­ment-re­lat­ed dis­cus­sions. If you live in Paris or want to vis­it Paris, you're very wel­come to con­tact me too.

Updated on July 17, 2022

Comments

  • Arseni Mourzenko
    Arseni Mourzenko almost 2 years

    I have a piece of JavaScript code which is expected to set an integer value to a variable.

    Something is broken, so when I try to do alert(A);, it returns NaN. isNaN(A); returns true. But if I alert(typeof(A));, it says number.

    So how can a variable be a number and not a number at the same time? Maybe I misunderstood what NaN really is?


    Edit: thanks to the answers, I see that I was wrong, because:

    • The type of NaN is Number,
    • NaN does mean "Not a number", which is not the same thing as "not of type Number",
    • 0/0 is a good example of NaN: it is still a number, but JavaScript (and nobody else) can say what is the real value of zero divided by zero. 1/0 on the other hand returns Infinity, which is not NaN.
  • Janick Bernet
    Janick Bernet almost 14 years
    Are you sure division by zero results in NaN and not in Inf? I think 0/0 results in NaN and trying to parse a string that does not represent a number.
  • Jani Hartikainen
    Jani Hartikainen almost 14 years
    Actually type of "NaN" is number, as little sense as it does. Non-representible numbers are "Infinity", not "NaN", although I have never seen the Infinity value in actual code.
  • Jani Hartikainen
    Jani Hartikainen almost 14 years
    typeof NaN == 'number'. This is why it appears to be of numeric type
  • Arseni Mourzenko
    Arseni Mourzenko almost 14 years
    1/0 is Infinity, and Infinity is not NaN. But I see the answer to my question. I misunderstood that NaN means, like you say, "numeric results that cannot be adequately represented", and not "not of type Number".
  • Arseni Mourzenko
    Arseni Mourzenko almost 14 years
    Thank you. I understand. And yes, 0/0 is NaN (contrary to 1/0).
  • tvanfosson
    tvanfosson almost 14 years
    @inflagranti - I had assumed that division by zero would be represented by NaN, but apparently not. My elementary school teacher would be really surprised by this: en.wikipedia.org/wiki/Division_by_zero
  • Jason S
    Jason S almost 14 years
    "1/0" yields Infinity. "-1/0" yields -Infinity. "0/0" yields NaN
  • Jason S
    Jason S almost 14 years
    0/0 yields NaN. All other instances of division by zero yields either +/-Infinity.
  • Arseni Mourzenko
    Arseni Mourzenko almost 14 years
    JavaScript has a really strange behavior when dealing with overflows. Never thought (Number.MAX_VALUE) * 2 will give Infinity.
  • Jason S
    Jason S almost 14 years
    why is that strange? ECMA-262 rev 3 sec 11.6.3 says: "In the remaining cases, where neither an infinity, nor a zero, nor NaN is involved, and the operands have the same sign or have different magnitudes, the sum is computed and rounded to the nearest representable value using IEEE 754 round-to-nearest mode. If the magnitude is too large to represent, the operation overflows and the result is then an infinity of appropriate sign. The ECMAScript language requires support of gradual underflow as defined by IEEE 754." (my emphasis)
  • Jason S
    Jason S almost 14 years
    (that was for addition, but 11.5.1 says the same thing about multiplication)
  • tvanfosson
    tvanfosson almost 14 years
    @Jason S -- I realize this now, but I still think that's strange behavior for integral numbers. Consider: I want to divide 4 things among 2 people -- each gets 2 things. Now, say I want to divide 4 things among zero people. It's arrant nonsense to say that each of 0 people gets an infinite number of things when there are only 4 things to have. It only really makes sense when we consider that it's probably doing IEEE754 floating point arthimetic despite the fact that we're using integral values, where those values are explicitly defined that way.
  • Jason S
    Jason S almost 14 years
    Javascript does not have integers; it only has IEEE754 floating-point numbers (see ECMA-262 standard 3rd edition section 8.5)
  • tvanfosson
    tvanfosson almost 14 years
    @Jason - I shouldn't have said probably -- an artifact of inline editing. I knew that it only did floating point arithmetic, I just wasn't thinking about that when I answered the question. Even with that, I obviously didn't remember that IEEE 754 defined division of a non-zero by zero has +/- infinity. Personally, I'd check for zero before doing the division.
  • Java Drinker
    Java Drinker almost 14 years
    @tvanfosson -- Interesting philosophical digression: "Now, say I want to divide 4 things among zero people. It's arrant nonsense to say that each of 0 people gets an infinite number of things when there are only 4 things to have". Well in the case of 4 things and 2 people, you give 2 each, and then if you want it back, they give you 2 each back. But the giving to zero is like dropping into an abyss... If you want it back, well the abyss needs to be full (which it cannot be...)... so I'm not sure it's nonsense, but fun anyway :-)
  • Andrzej Doyle
    Andrzej Doyle almost 14 years
    Thanks to all - I've corrected the post appropriately to use 0/1 as an example of NaN. It's impressive that I can learn something from an answer marked as correct - go go StackOverflow!
  • Janick Bernet
    Janick Bernet almost 14 years
    @tvanfosson: Your elementary school teacher my be suprised that 1/0 is infinity, your high school teacher much less so ;) It is arguably however not correct that 1/0 = inf, rather lim(1/0) = inf; though I think thats mathetmatically nitpicking...
  • tvanfosson
    tvanfosson almost 14 years
    @inflaganti - more nitpicking lim(1/n) as n -> 0 = +inf for positive n and -inf for negative n. The function 1/n and the limit (non-one-sided) are both undefined at 0.
  • Joshua Dance
    Joshua Dance over 10 years
    Adding in a few relevant bits to this answer would make it even better.
  • AaronLS
    AaronLS over 10 years
    @AndrzejDoyle This being the accepted answer, I would enourage you to add an example of another instance that you will get NaN result: attempting to perform math when one of the operators is unassigned: var percent; var test = percent * 100; will yield NaN result because we never assigned percent a number.