why does "Infinity==Infinity" in JavaScript becomes true? - javascript

As far as I know, in math both Infinity and NaN are vague values.
as all of us know:
console.log(NaN == NaN); //-> false
while
console.log(Infinity==Infinity); //-> true
I'm wondering why the result of the second code is true. I'm expecting that the result of the second one, should be false, but it's not.
Could you please help me out.
I'd really appreciate it. Thanks.

This is why:
NaN compares unequal (via ==, !=, ===, and !==) to any other value -- including to another NaN value. Use Number.isNaN() or isNaN() to most clearly determine whether a value is NaN. Or perform a self-comparison: NaN, and only NaN, will compare unequal to itself.
Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN
The initial value of Infinity is Number.POSITIVE_INFINITY. The value Infinity (positive infinity) is greater than any other number. This value behaves mathematically like infinity; for example, any positive number multiplied by Infinity is Infinity, and anything divided by Infinity is 0.
Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity
What you also might be interested in is using the isFinite method of Number:
Number.isFinite(Infinity); // false
Number.isFinite(NaN); // false
Read up on Number.isFinite(): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite

In addition to the other answers: Because the spec says so.
NaN is the only value in JavaScript that is not equal to itself:
A reliable way for ECMAScript code to test if a value X is a NaN is an expression of the form X !== X. The result will be true if and only if X is a NaN.
http://www.ecma-international.org/ecma-262/5.1/#sec-15.1.2.4

Because processors interpret it that way. Most math in JS follows the IEEE-754 specification for floating math arithmetic, which processors implement in pretty specific ways. That includes NaN !== NaN and Infinity === Infinity, among other things.

infinity is treated as a numeric value, so infinity==infinity represents one numeric value equaling another. While in common mathematics the infinity can not be compared against infinity, in javascript it can!
NaN on the other hand, is a type of undefined variable, not a number. So comparisons between NaN are not logically comparable. The proper way to compare against NaN is with the function isNaN.
Example:
isNaN(NaN) // returns true

Related

EloquentJavaScript: !Number.isNaN() what is the purpose? [duplicate]

Soooooo isNaN is apparently broken in JavaScript, with things like:
isNaN('')
isNaN(' ')
isNaN(true)
isNaN(false)
isNaN([0])
Returning false, when they appear to all be... Not a Number...
In ECMAScript 6, the draft includes a new Number.isNaN but it looks like (imo) that this is also broken...
I would expect
Number.isNaN('RAWRRR')
To return true, since it's a string, and cannot be converted to a number... However...
It seems that things that I would consider... not a number, are indeed, not, not a number...
http://people.mozilla.org/~jorendorff/es6-draft.html#sec-isfinite-number
The examples on MDN say:
Number.isNaN("blabla"); // e.g. this would have been true with isNaN
I don't understand how this is "More robust version of the original global isNaN." when I cannot check to see if things are not a number.
This would mean we're still subjected to doing actual type checking as well as checking isNaN... which seems silly...
http://people.mozilla.org/~jorendorff/es6-draft.html#sec-isnan-number
The ES3 draft here basically says, everything is always false, except with its Number.NaN
Does anyone else find this is broken or am I just not understanding the point of isNaN?
isNaN() and Number.isNaN() both test if a value is (or, in the case of isNaN(), can be converted to a number-type value that represents) the NaN value. In other words, "NaN" does not simply mean "this value is not a number", it specifically means "this value is a numeric Not-a-Number value according to IEEE-754".
The reason all your tests above return false is because all of the given values can be converted to a numeric value that is not NaN:
Number('') // 0
Number(' ') // 0
Number(true) // 1
Number(false) // 0
Number([0]) // 0
The reason isNaN() is "broken" is because, ostensibly, type conversions aren't supposed to happen when testing values. That is the issue Number.isNaN() is designed to address. In particular, Number.isNaN() will only attempt to compare a value to NaN if the value is a number-type value. Any other type will return false, even if they are literally "not a number", because the type of the value NaN is number. See the respective MDN docs for isNaN() and Number.isNaN().
If you simply want to determine whether or not a value is of the number type, even if that value is NaN, use typeof instead:
typeof 'RAWRRR' === 'number' // false
No, the original isNaN is broken. You are not understanding the point of isNaN.
The purpose of both of these functions is to determine whether or not something has the value NaN. This is provided because something === NaN will always be false and therefore can't be used to test this.
(side note: something !== something is actually a reliable, although counter-intuitive, test for NaN)
The reason isNaN is broken is that it can return true in cases when a value is not actually NaN. This is because it first coerces the value to a number.
So
isNaN("hello")
is true, even though "hello" is not NaN.
If you want to check whether a value actually is a finite number, you can use:
Number.isFinite(value)
If you want to test whether a value is a finite number or a string representation of one, you can use:
Number.isFinite(value) || (Number.isFinite(Number(value)) && typeof value === 'string')
As mentioned in a comment isNaN() and Number.isNaN() both check that the value you pass in is not equal to the value NaN. The key here is that NaN is an actual value and not an evaluated result e.g. "blabla" is a String and the value is "blabla" which means it is not the value "NaN".
A plausible solution would be doing something like:
Number.isNaN(Number("blabla")); //returns true.
The key difference between the two is that the global isNaN(x) function performs a conversion of the parameter x to a number. So
isNaN("blabla") === true
because Number("blabla") results in NaN
There are two definitions of "not a number" here and that's perhaps where the confusion lies. Number.isNaN(x) only returns true for the IEEE 754 floating point specification's definition of Not a Number, for example:
Number.isNaN(Math.sqrt(-1))
as opposed to determining whether the object being passed in is of numeric type or not. Some ways of doing that are:
typeof x === "number"
x === +x
Object.prototype.toString.call(x) === "[object Number]"
Basically, window.isNaN performs a type conversion to a number, then checks if it is NaN. Whereas, Number.isNaN doesn't try to convert its argument to a number. So basically, you can think of window.isNaN, and Number.isNaN as working like so.
window.isNaN = function(n){
return Number(n) !== Number(n);
}
window.Number.isNaN = function(n){
return n !== n;
}
Please note that you don't need actually to use the window. to call isNaN or Number.isNaN. Rather, I am just using it to provide a better distinction between the two similarly-named methods to try to cut down on confusion.
~ Happy Coding!
The following works because NaN is the only value in javascript which is not equal to itself.
Number.isNaN = Number.isNaN || function(value) {
return value !== value;
}
Per, MDN, it (NaN) is the returned value when Math functions fail and as such it is a specific value. Perhaps a better name would have been, MathFunctionFailed.
To determine if something is a number requires parsing which fails nicely over a broad range of non numeric inputs, successfully detecting numbers and strings representing numbers, hence:
function isNumber(v) {return Number.isNaN(parseFloat(v)); }
1. Number.isNaN
alert(Number.isNaN('Hello')); // false
Shouldn't it return true because Hello is a string and its Not A Number right ? But Lets know why it returns false.
MDN docs says :
true if the given value is NaN and its type is Number; otherwise,
false.
Yes Hello value is NaN but the type is string , you can check the type as follows:
alert(typeof `Hello`); // string
Usage:
Use when you want to check the value is both NaN and type is number.
2. isNaN
alert(isNaN('Hello')); // true
MDN docs says:
true if the given value is NaN; otherwise, false.
Usage:
Use when you want to check value is just NaN.
3. jQuery.isNumeric()
Jquery Docs Says :
Determines whether its argument represents a JavaScript number.
alert($.isNumeric('Hello')); // false
alert($.isNumeric(3)); //true
Usage:
Use when you want to check value is a number or can be converted to a number.
Reference
I use a simple workaround to check Number.isNaN():
let value = 'test';
Number.isNaN(-value); // true
value = 42;
Number.isNaN(-value); // false
js trying to convert the value to the negative Number, if the conversion is failed - we have NaN.
Simple, isn't it?
Moreover, online benchmark tests say Number.isNaN is lighter than isNaN.
Number.isNaN(x) checks if x is directly evaluated to NaN or not.
RAWR is not the same as NaN. Think of NaN as an entity to represent the result of some mathematical calculation where the computer does not know how to represent the number.
A mathematical operation is not going to yield a non-numeric result, hence the typeof NaN is number.
The string RAWR had undergone no mathematical operation to yield NaN. However, if you were to call Number.isNaN(+'RAWR'), it would result in NaN since the unary + operator is trying to convert 'RAWR' to a number.
On the other hand, isNaN(y) tells whether y can be converted to a number or not. If isNaN(y) is false, y can be converted to a number. But if isNaN(y) is true, y can not be converted to a number.
So a good rule of thumb is:
Do I want to check if x can be successfully converted to a number? Use isNaN(x) == false in that case. Unsuccessful conversion results in NaN.
Do I want to check if x is evaluated to NaN? Use Number.isNaN(x) == true for that.
#phill, as stated in other responses, neither is broken.
Number.isNaN work on a number or instance of Number, so even Number.isNaN(new Date(NaN)) is false.
isNaN, on the other hand, is generic and tries to convert its parameter to a number before checking it.
If you want to determine if a value is (or contains) NaN, you can use this function:
function valueIsNaN(value) {
// eslint-disable-next-line no-self-compare
return value !== value || typeof value == 'object' && Number.isNaN(value.valueOf());
}

Comparing NaN in javascript [duplicate]

This question already has answers here:
How do I test for NaN? [duplicate]
(2 answers)
Closed 7 years ago.
In Javascript, if we multiply a string with number we get NaN:
console.log("manas" * 5); // result is NaN
Why then does the following code result in false instead of true?
console.log("manas" * 5 == NaN) // results false
Use the isNaN function instead.
console.log(isNaN("manas" * 5));
http://www.w3schools.com/jsref/jsref_isnan.asp
NaN, not a number, is a special type value used to denote an unrepresentable value. With JavaScript, NaN can cause some confusion, starting from its typeof and all to the way the comparison is handled.
Several operations can lead to NaN as the result.
Because there are many ways to represent a NaN, it makes sense that one NaN will not be equal to another NaN.
NaN is a special numeric value which is not equal to anything including itself. To properly test for NaN you need to use isNaN function.
From specification:
Returns true if the argument coerces to NaN, and otherwise returns false.
Here is also useful note from the same ECMAScript section:
A reliable way for ECMAScript code to test if a value X is a NaN is an expression of the form X !== X. The result will be true if and only if X is a NaN.
NaN compares unequal (via ==, !=, ===, and !==) to any other value -- including to another NaN value. Use Number.isNaN() or isNaN() to most clearly determine whether a value is NaN. Or perform a self-comparison: NaN, and only NaN, will compare unequal to itself.
Testing against NaN
In Javascript,
NaN == NaN //always results false.
(self comparison of NaN to itself is always false in javascript)
refer:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN
also see Is NaN equal to NaN?
Javascript is not that smart - when either side of the == operator is Nan, the whole thing evaluates as false (similar to how if leftside of || is false, it doesn't bother looking at right side)
So, even Nan == Nan will return false.
Here's a good article on Nan behaviour
http://ariya.ofilabs.com/2014/05/the-curious-case-of-javascript-nan.html

How does JavaScript evaluate if statement expressions?

I always thought that JavaScript's if statements did some kind of casting magic to their arguments, but I'm a little wary of what's actually going on behind the scenes.
I recently found a JavaScript comparison table and noticed that even though -1 == true evaluates to false, if(-1){...} will execute.
So within JavaScripts if statements, what happens to the expression? It seems reasonable to assume that it uses !!{expression} to cast it to an inverse boolean, then invert it again, but if that's the case, how does JS decide whether an object's inverse boolean representation is truthy or not?
JavaScript is wonky.
Yes, -1 == true results in false, but that's not what the if statement is doing. It's checking to see if the statement is 'truthy', or converts to true. In JavaScript, that's the equivalent of !!-1, which does result in true (all numbers other than zero are truthy).
Why?!?
The spec defines the double equals operator to do the following when presented with a number and a boolean:
If Type(y) is Boolean, return the result of the comparison x == ToNumber(y).
ToNumber will convert the boolean true into the number 1, so you're comparing:
-1 == 1
which anyone can tell you is clearly false.
On the other hand, an if statement is calling ToBoolean, which considers any non-zero, non-NaN number to be true.
Any JavaScript developer really needs to look at the documentation -- for this case, located here: http://www.ecma-international.org/ecma-262/5.1/#sec-9.2
9.2 ToBoolean
The abstract operation ToBoolean converts its argument to a value of type Boolean according to Table 11:
Argument Type Result
Undefined false
Null false
Boolean The result equals the input argument (no conversion).
Number The result is false if the argument is +0, −0, or NaN; otherwise the result is true.
String The result is false if the argument is the empty String (its length is zero); otherwise the result is true.
Object true
(Sorry about the formatting, can't make a table here.)
From JavaScript The Definitive Guide
The following values convert to, and therefore work like, false:
undefined
null
0
-0
NaN
"" // the empty string
All other values, including all objects (and arrays) convert to, and work like, true. false, and the six values that convert to it, are sometimes called falsy values, and all other values are called truthy.
These things by themselves are falsy (or evaluate to false):
undefined
null
0
'' or ""
false
NaN
Everything else i truthy.
Truthy-ness or falsy-ness is used when evaluating a condition where the outcome is expected to be either truthy (true) or falsy (false).
In your example if(-1 == true), you are comparing apples and oranges. The compare is evaluated first (and resulted in false), and the results of that is used in your condition. The concept of truthyness/falsyness isn't applied to the operands the comparison.
When if state using with comparing variable different type js use .toString и .valueOf ( for more information check http://javascript.info/tutorial/object-conversion ) - just keep this in mind - it make so example much more easy to understand

how a string object transforms when compared?

console.log("20">10); //true
console.log("20a">"10"); //true
console.log("20a">10); //false
I want to know why the last one turns false.
And "20a" transforms to what before comparing.
From the MDN page on comparison operators:
For relational abstract comparisons (e.g. <=), the operands are first converted to primitives, then the same Type, before comparison.
console.log("20">10); //true
This converts "20" to a number 20 and compares it. Since 20 is greater than 10, it is true.
console.log("20a">"10"); //true
This compares the two strings. Since "20a" is greater (alphabetically) than "10", it is true.
console.log("20a">10); //false
This converts "20a" to a number. The result is NaN (do +"20a" to see this in action). NaN is not greater than any number, so it returns false.
The comparison algoritm in ECMAScript is described here : http://bclary.com/2004/11/07/#a-11.8.5
The comparison x < y, where x and y are values, produces true, false,
or undefined (which indicates that at least one operand is NaN). Such
a comparison is performed as follows:
Call ToPrimitive(x, hint Number).
Call ToPrimitive(y, hint Number).
3.If Type(Result(1)) is String and Type(Result(2)) is String, go to step 16. (Note that this step differs from step 7 in the algorithm for
the addition operator + in using and instead of or.)
4.Call ToNumber(Result(1)).
5.Call ToNumber(Result(2)).
...
So in case of "20a">10, the javascript engine must apply ToNumber to "20a". The complete algorithm is complex but states that
If the grammar cannot interpret the string as an expansion of
StringNumericLiteral, then the result of ToNumber is NaN.
So you're comparing NaN to 10 and any comparison involving NaN returns false (or undefined, see comments below).
For the last case, Notice that even "20a" < 10 return false. This highlights the evaluation of "20a" at NaN during the comparison, as NaN compared to any number always returns false.

Why does isNaN(123.) return false?

Why does the Javascript function call isNaN(123.) return false? (notice the dot (.) after 123). Is this a universally acceptable number or will it cause errors downstream?
I'm validating whether a value is a valid decimal using isNaN along with split. Are there cross-browser issues with isNaN? Should I use a bespoke implementation?
Thanks.
In JavaScript the grammar of a Numeric Literal is expressed like this:
DecimalIntegerLiteral . DecimalDigitsopt ExponentPartopt
As you can see the DecimalDigits part after the dot is optional (opt suffix).
var n = 123.;
typeof n; // "number"
I wouldn't recommend the isNaN function to detect numbers, since type coercion can make some things look strange:
isNaN(""); // false, a empty string coerces to zero
isNaN("\n\t"); // false, a white-space string coerces to zero
isNaN(true); // false, boolean true coerces to 1
isNaN(false); // false, boolean false coerces to zero
isNaN(new Date); // false, Date objects coerce to its numeric timestamp
// etc...
isNaN should be used only to compare against NaN, since:
NaN == NaN; // false!
IsNaN(NaN); // true
If you want to detect Number objects, Number values or "parseable" numeric strings, give a look to this function I've posted some time ago.
NaN or (not a number) is a particular floating-point value, meaning a value that cannot be represented by computers (using the IEEE 754 floating point standard).
Crucially for you, the isNaN() function makes a best-effort to translate numbers to floating-point, which is why your example returns true. See, for example:
isNaN(100); //Returns false
isNaN("100"); //Returns false
isNaN("ABC"); //Returns true
isNaN("10C"); //Returns true
isNaN(Math.sqrt(-1)); //Returns true
If you want to access a number such as "123." as a float, try using parseFloat():
parseFloat("123."); //Returns 123
Furthermore, 123. is a valid number in javascript, which doesn't require a fractional part after the decimal point. So isNan() is behaving correctly, and should return false in this case.
The function is called "is Not a Number". So, this should return false in case you enter a number and true if it isn't. Even with the dot behind it this number is still valid. 123. just validates as 123 or 123.0.

Categories

Resources