Alright so I've been learning Javascript for 3 months and have gotten some pretty good exposure to solving several tasks. At the beginning of my book they have examples of NaN but they usually involve things like
NaN === NaN; // false
Number.NaN === NaN; // false
isNaN(NaN); // true
isNaN(Number.NaN); // true
I've even looked on other stackoverflow posts and I still don't see a scenario of where I can use it in. That being said, in what situations does this global property help me? What are some practical situations in an actual program?
NaN is the number which results from math operations which make no sense:
Number('abc'); // NaN
0 / 0; // NaN
Math.sqrt(-1); // NaN
Math.log(-1); // NaN
Math.asin(2); // NaN
When you do some math opertion and some operand is NaN, it will propagate to the result:
NaN + 2; // NaN
NaN * 0; // NaN
1 / NaN; // NaN
Math.pow(NaN, 2); // NaN
NaN is most useful when you have a value that's not a number (but ought to have been). You'll only get NaN back from the standard APIs in a few places, in particular parseInt:
The parseInt function converts its first argument to a string, parses it, and returns an integer or NaN.
Much of the value here is that once NaN has been introduced to a chain of math operators, the operations are defined (even if they wouldn't have made sense with the initial operands, thus producing NaN) and will continue returning NaN. Most of the math operators, as you can see from the / instructions, have a clause to immediately return NaN if either operand is already not a number.
Related
What could be the reason to make these two functions behave differently for values infinity and -infinity. Does anyone ever find this inconsistency useful?
parseInt(Infinity); // NaN
parseFloat(Infinity); // Infinity
The answer to that question is right in the specs for the two functions:
parseInt takes a string parameter.
If the first character cannot be converted to a number, parseInt returns NaN.
parseFloat
parseFloat can also parse and return the value Infinity. You can use the isFinite function to determine if the result is a finite number (not Infinity, -Infinity, or NaN).
parseInt can't return infinity because infinity is not within JavaScript's integer range. whereas it is a valid within the floating point range.
As for useful? I can't say. In the domain that I work in, NaN means an error has happened and I don't believe I have ever used infinity
This question already has answers here:
Why does typeof NaN return 'number'?
(21 answers)
Closed 7 years ago.
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
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
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.
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().
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).
it's not related to angular, it's JavaScript
try this
typeof NaN
it will return number
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.
How can this be false?
console.log(parseInt(undefined));
//NaN
console.log(parseInt(undefined)===NaN);
//false
That seems dumb
NaN is not equal to anything, even itself. Use isNaN to detect NaN instead of an equality.
NaN === NaN // -> false
isNaN(NaN) // -> true (argument is coerced [ToNumber] as required)
x = NaN
x !== x // -> true (would be false for any other value of x)
NaN || "Hi" // -> "Hi" (NaN is a false-y value, but not false)
This is a result of JavaScript following IEEE-754 and it's (quiet) NaN lack-of-ordering behavior:
A comparison with a NaN always returns an unordered [not equal] result even when comparing with itself.
See also What is the rationale for all comparisons returning false for IEEE754 NaN values?
Its because NaN === NaN is also false!
NaN is not equal to itself and the reason can be understood from the answer posted by Stephen here:
My understanding from talking to Kahan is that NaN != NaN originated
out of two pragmatic considerations:
that x == y should be equivalent to x - y == 0 whenever possible (beyond being a theorem of real arithmetic, this makes hardware
implementation of comparison more space-efficient, which was of utmost
importance at the time the standard was developed — note, however,
that this is violated for x = y = infinity, so it’s not a great reason
on its own; it could have reasonably been bent to x - y == 0 or
NaN).
more importantly, 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. I’ll quote Kahan’s own
writing on the subject:
Were there no way to get rid of NaNs, they would be as useless as Indefinites on CRAYs; as soon as one were encountered, computation
would be best stopped rather than continued for an indefinite time to
an Indefinite conclusion. That is why some operations upon NaNs must
deliver non-NaN results. Which operations? … The exceptions are C
predicates “ x == x ” and “ x != x ”, which are respectively 1 and 0
for every infinite or finite number x but reverse if x is Not a Number
( NaN ); these provide the only simple unexceptional distinction
between NaNs and numbers in languages that lack a word for NaN and a
predicate IsNaN(x).
Note that this is also the logic that rules out returning something
like a “Not-A-Boolean”. Maybe this pragmatism was misplaced, and
the standard should have required isnan( ), but that would have made
NaN nearly impossible to use efficiently and conveniently for several
years while the world waited for programming language adoption. I’m
not convinced that would have been a reasonable tradeoff.
While working in my JS code today, I found the following situation and can not explain myself what should be the correct output ?
'sachin' > 2 // False
'sachin' < 2 // False
'sachin' == 2 // False
I expect result of either of < or > should be true. What am I missing ?
When the runtime attempts to convert 'sachin' to a number, it will fail and end up as NaN. That special constant results in false for any comparison to any other numeric value. The NaN constant ("Not A Number") is not equal to any other value, nor is it less than or greater than any other value.
edit — the ==, <, and > operators all "prefer" numbers to strings. If one operand is a number and the other a string, they'll always try to interpret the string as a number. It doesn't matter what order the operands appear in; what matters is the operand types.
(Strictly speaking, the results of < and > when NaN is involved are supposed to be undefined, according to the spec, but Firefox seems to give false instead.)
This question already has answers here:
What is the rationale for all comparisons returning false for IEEE754 NaN values?
(12 answers)
Closed 10 years ago.
Why are these two different?
var x = NaN; //e.g. Number("e");
alert(isNaN(x)); //true (good)
alert(x == NaN); //false (bad)
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.
The equality and inequality predicates are non-signaling so x = x returning false can be used to test if x is a quiet NaN.
Source
This is the rule defined in IEEE 754 so full compliance with the specification requires this behavior.
The following operations return NaN
The divisions 0/0, ∞/∞, ∞/−∞, −∞/∞, and −∞/−∞
The multiplications 0×∞ and 0×−∞
The power 1^∞
The additions ∞ + (−∞), (−∞) + ∞ and equivalent subtractions.
Real operations with complex results:
The square root of a negative number
The logarithm of a negative number
The tangent of an odd multiple of 90 degrees (or π/2 radians)
The inverse sine or cosine of a number which is less than −1 or greater than +1.
The following operations return values for numeric operations. Hence typeof Nan is a number. NaN is an undefined number in mathematical terms. ∞ + (-∞) is not equal to ∞ + (-∞). But we get that NaN is typeof number because it results from a numeric operation.
From wiki: