Why Is Nan === Nan False

Why is NaN === NaN false?

Strict answer: Because the JS spec says so:

  • If Type(x) is Number, then
    • If x is NaN, return false.
    • If y is NaN, return false.

Useful answer: The IEEE 754 spec for floating-point numbers (which is used by all languages for floating-point) says that NaNs are never equal.

Is NaN falsy? Why NaN === false returns false

  1. Falsy and being strictly equal to false are very different things, that's why one has a y instead of an e. ;)
  2. NaN is spec'd to never be equal to anything. The second part of your question is comparing false === false, which is funnily enough, true :)

If you really want to know if something is NaN, you can use Object.is(). Running Object.is(NaN, NaN) returns true.

Why does NaN = !NaN return true?

You are assigning true to NaN instead of comparing NaN to !NaN using === or ==, so the operation returns the assigned value -> true. Javascript ignores this assignment silently because NaN is read only.

console.log(NaN = true);
// NaN hasn't changedconsole.log(NaN);

Why is NaN not equal to NaN?

My original answer (from 4 years ago) criticizes the decision from the modern-day perspective without understanding the context in which the decision was made. As such, it doesn't answer the question.

The correct answer is given here:

NaN != NaN originated out of two pragmatic considerations:

[...] There was no isnan( ) predicate at the time that NaN was formalized in the 8087 arithmetic; it was necessary to provide programmers with a convenient and efficient means of detecting NaN values that didn’t depend on programming languages providing something like isnan( ) which could take many years

There was one disadvantage to that approach: it made NaN less useful in many situations unrelated to numerical computation. For example, much later when people wanted to use NaN to represent missing values and put them in hash-based containers, they couldn't do it.

If the committee foresaw future use cases, and considered them important enough, they could have gone for the more verbose !(x<x & x>x) instead of x!=x as a test for NaN. However, their focus was more pragmatic and narrow: providing the best solution for a numeric computation, and as such they saw no issue with their approach.

===

Original answer:

I am sorry, much as I appreciate the thought that went into the top-voted answer, I disagree with it. NaN does not mean "undefined" - see http://www.cs.berkeley.edu/~wkahan/ieee754status/IEEE754.PDF, page 7 (search for the word "undefined"). As that document confirms, NaN is a well-defined concept.

Furthermore, IEEE approach was to follow the regular mathematics rules as much as possible, and when they couldn't, follow the rule of "least surprise" - see https://stackoverflow.com/a/1573715/336527. Any mathematical object is equal to itself, so the rules of mathematics would imply that NaN == NaN should be True. I cannot see any valid and powerful reason to deviate from such a major mathematical principle (not to mention the less important rules of trichotomy of comparison, etc.).

As a result, my conclusion is as follows.

IEEE committee members did not think this through very clearly, and made a mistake. Since very few people understood the IEEE committee approach, or cared about what exactly the standard says about NaN (to wit: most compilers' treatment of NaN violates the IEEE standard anyway), nobody raised an alarm. Hence, this mistake is now embedded in the standard. It is unlikely to be fixed, since such a fix would break a lot of existing code.

Edit: Here is one post from a very informative discussion. Note: to get an unbiased view you have to read the entire thread, as Guido takes a different view to that of some other core developers. However, Guido is not personally interested in this topic, and largely follows Tim Peters recommendation. If anyone has Tim Peters' arguments in favor of NaN != NaN, please add them in comments; they have a good chance to change my opinion.

JavaScript : What is the value of NaN

NaN means "Not A Number". It is a special value that denotes the result of a computation that either is impossible (division by zero, f.e.) or cannot be stored using the floating point format. It represents a value that is unknown or cannot be computed (or stored) using the floating point format.

The comparison of NaN with anything else does not make any sense. NaN is not equal even to itself. This happens because it is not a certain value. Being an unknown value, most probably it is not equal to a different unknown value.

Read more in the documenation of NaN.

Why in numpy `nan == nan` is False while nan in [nan] is True?

nan not being equal to nan is part of the definition of nan, so that part's easy.

As for nan in [nan] being True, that's because identity is tested before equality for containment in lists. You're comparing the same two objects.

If you tried the same thing with two different nans, you'd get False:

>>> nans = [float("nan") for i in range(2)]
>>> map(id, nans)
[190459300, 190459284]
>>> nans
[nan, nan]
>>> nans[0] is nans[1]
False
>>> nans[0] in nans
True
>>> nans[0] in nans[1:]
False

Your addendum doesn't really have much to do with nan, that's simply how Python works. Once you understand that float("nan") is under no obligation to return some nan singleton, and that y = x doesn't make a copy of x but instead binds the name y to the object named by x, there's nothing left to get.

Why is IsNaN(x) different from x == NaN where x = NaN

Nothing is equal to NaN. Any comparison will always be false.

In both the strict and abstract comparison algorithms, if the types are the same, and either operand is NaN, the result will be false.

If Type(x) is Number, then

  • If x is NaN, return false.
  • If y is NaN, return false.

In the abstract algorithm, if the types are different, and a NaN is one of the operands, then the other operand will ultimately be coerced to a number, and will bring us back to the scenario above.



Related Topics



Leave a reply



Submit