views:

182

answers:

6

Hi,

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.
+10  A: 

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.

tvanfosson
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.
inflagranti
typeof NaN == 'number'. This is why it appears to be of numeric type
Jani Hartikainen
@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: http://en.wikipedia.org/wiki/Division_by_zero
tvanfosson
"1/0" yields Infinity. "-1/0" yields -Infinity. "0/0" yields NaN
Jason S
@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.
tvanfosson
Javascript does not have integers; it only has IEEE754 floating-point numbers (see ECMA-262 standard 3rd edition section 8.5)
Jason S
@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.
tvanfosson
@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 :-)
Java Drinker
@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...
inflagranti
@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.
tvanfosson
+2  A: 

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).

Andrzej Doyle
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
`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`".
MainMa
0/0 yields NaN. All other instances of division by zero yields either +/-Infinity.
Jason S
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!
Andrzej Doyle
+1  A: 

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.

inflagranti
Thank you. I understand. And yes, `0/0` is `NaN` (contrary to `1/0`).
MainMa
A: 

Along with what has been said I think if you divide by for example a string. It trys to returns NaN but still looks at it as a number.

qw3n
A: 

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

Jørgen Fogh
+1  A: 

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
JavaScript has a really strange behavior when dealing with overflows. Never thought `(Number.MAX_VALUE) * 2` will give `Infinity`.
MainMa
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 nearestrepresentable 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 ECMAScriptlanguage requires support of gradual underflow as defined by IEEE 754." (my emphasis)
Jason S
(that was for addition, but 11.5.1 says the same thing about multiplication)
Jason S