Why can not I use comparison operators with NaN?

5
  

NaN - The global NaN property is a special value that means Not-A-Number (not a number).

The curious thing is that it is not possible to perform operations of comparison with this almost mystical property. Featuring a nonreflective feature where NaN === NaN is false.

I made below a javascript code executable just to test the concept, but could be any programming language.

var spans = document.querySelectorAll('span');
for(var i  in spans){
 var span = spans[i];
 if(span && typeof span.getAttribute == 'function'){
  var exp = span.getAttribute("data-evaluate");
  console.log(exp, eval(exp));
  span.innerHTML = "Expr: "+ exp + " ------------ :> " + eval(exp);
 }
}
<span data-evaluate="true"></span><br> <!-- eval control -->
<span data-evaluate="isNaN(NaN)"></span><br><!-- NaN control -->
<span data-evaluate="NaN === NaN"></span><br>
<span data-evaluate="parseInt('A') === NaN"></span><br>
<span data-evaluate="parseInt('1') === NaN"></span><br>
<span data-evaluate="parseInt('B') === parseInt('B')"></span>

If you usually perform arithmetic calculations in your code, it is possible for NaN to appear naturally, whether it is conversion with type-to-type conversion (string for int, for example), or the sum with undefineds .

What is the concept, the mathematics behind this anomaly, and what makes NaN so confusing that it prevents a simple NaN === NaN from returning a false value although humanly speaking it should return true?

    
asked by anonymous 13.07.2017 / 20:12

2 answers

7

NaN, + inf, -inf are attempts to model exceptions, errors, undeterminations, and overflows to arithmetic. Floating point representations (ex Double of C) have conventions to represent these pseudo numbers .

There are several situations that return (drop) NaN, + inf, -inf

Let's start with a more intuitive case - inf:

5 / 0    = +inf
-5/ 0    = -inf
n + n ...= +inf  se tiver havido overflow
log(0)   = -inf

NaN cases often result in inf or the "indeterminacy" 0/0

0 / 0     = NaN
5/0+ -5/0 = +inf -inf = NaN
+inf * 0  = NaN
inf / inf = NaN
+inf -inf = NaN
sqrt(-1)  = NaN

NaN + ... = NaN
NaN / ... = NaN
NaN * ... = NaN

5 * +inf  = +inf
-2 * +inf = -inf
5  / inf  = 0

The various NaNs are not equal to each other - hence NaN == NaN is false. The comparisons involving NaN and inf are generally undefined:

+inf > +inf      ???
NaN  > NaN       ???
0/0  > sqrt(-1)  ???

I suggest reading the data.represent , where this subject is expanded.

    
14.07.2017 / 14:35
4
  

NaN are generated when arithmetic operations have the following values:    undefined or unrepresentable . As values, they do not necessarily   overflow conditions. NaN also results from the conversion attempt and   non-numeric values for numeric values so that the numeric value   primitive is available.

This value conversion generates arithmetic binary values by preventing arithmetic operations, the obvious thing would be that NaN === NaN would result in a positive Boolean value, since we are only looking at "NaN" as if it were a constant, and in fact it does not is. For example "A" * "A" and parseInt("blabla") result in NaN but are completely different in their primitive numerical value.

In the floating point calculations (IEEE 754) , NaN is not the same as Infinity although both are typically treated as special cases in floating point representations of real numbers as well as in floating point operations. An invalid operation is also not the same as% arithmetic% (which can return an infinity) or an arithmetic%% (which would return the smallest normal number, a normal number or zero).

A comparison with a NaN always returns an unordered result, even when compared to itself. The predicates of comparison are signaling or non-signaling; Signaling versions indicate the invalid operation exception for such comparisons. The equality and inequality predicates are not flags, so x = x return false can be used to test if x is a silent NaN. The other standard comparison predicates are all signaling if they receive a NaN operand, the standard also provides non-signaling versions of these other predicates.

Summarizing NaN does not represent the set of all real numbers. And infinite real values will produce the same finite or infinite floating point result regardless of the substitutions. Preventing arithmetic operations from being performed on this type of data.

    
13.07.2017 / 22:34