4

NaN represents Not-A-Number.

It appears that angular.isNumber thinks it is a number. (angularjs 1.4.2) Why does angular.isNumber return true for NaN input?

thanks

mduf
  • 69
  • 1
  • 5

6 Answers6

3

Quoting IgorMinar, Angular Developer in this exact question:

$ node
> typeof NaN
'number'

It kind of makes sense if you squint with both eyes and plug your ears.

If you deliberately use NaN in your app, you should use isNaN instead of angular.isNumber.

I'm inclined to say that the current behavior, even though a bit surprising, is consistent with how NaN is being treated in javascript. If you have some good arguments for changing the behavior please share them with us.

So the question really goes for the javascript standard itself not for Angular

And to answer this question we must go to ECMAScript 5 specification of number type, of course it says:

4.3.20 Number type

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

4.3.23 NaN

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

So yes, according to the latest ECMAScript Specification i'm a number

NaN
  • 485
  • 3
  • 12
1

Here's the best way that I can think of to explain this.

Although the value of NaN represents something that is not a number, the value NaN itself is still a number type (in the type system sense).

It's also a defined value for a floating point number in IEEE 754, which is what JavaScript uses for numbers. It is sensible that values infinity and NaN would be number types.

jdphenix
  • 15,022
  • 3
  • 41
  • 74
1

The ECMA spec defines NaN as a IEEE 754 Not-a-Number number value. One reason for the NaN global being a number are comparison purposes. It is also needed to represent undefined numerical results, like the value of Math.sqrt(-1). So it’s not particularly AngularJS specific. Consider the following:

typeof NaN === "number"   // true
typeof NaN === typeof NaN // true
typeof NaN === typeof 123 // true
NaN === NaN  // false
isNaN(NaN)   // true
isNaN(123)   // false
isNaN('123') // false
isNaN('|23') // true

So isNumber returns true for NaN because it is a Number. To check for numerics, use isNaN().

dakab
  • 5,379
  • 9
  • 43
  • 67
0

it's not related to angular, it's JavaScript try this

typeof NaN

it will return number

Coding Enthusiast
  • 3,865
  • 1
  • 27
  • 50
Ahmed Eid
  • 1,145
  • 8
  • 9
0

Most likely angular just uses the type of what you pass in. if the type is number then it returns true.

If you want to know if something is a number (excluding NaN) you can do the following.

function isNumber(val){
  return angular.isNumber(val) && (val == val);
}

This works by first determing if val is a number. If it is check to see if it's NaN.

NaN is not equal to itself (or any other number for that matter).

Timothy Murphy
  • 1,322
  • 8
  • 16
0

There are really two meanings of "number" here:

  • the abbreviation "NaN" means that there is no meaningful answer to a particular mathematical operation; you could say "no such number"
  • however, every value in a language like JS has a type, and the type of data which goes into and out of mathematical operations is known in JS as "number"; thus when JS wants a special value to say that a mathematical operation has no answer, that special value is a special number

Note that this apparent contradiction is less obvious in other languages, because JS is unusual in having only one numeric type, rather than (at least) integer and real/float types. Having NaN as a floating point value is standard across pretty much all modern languages, but because of the word "number", it perhaps seems more surprising in JS.

The Angular function is one of a set of utilities for testing the type of a value. The documentation for it mentions that it returns true for infinities and NaN, and points to the standard isFinite function for when that's not desirable.

IMSoP
  • 89,526
  • 13
  • 117
  • 169