Reputation: 1117
I have this code:
function getSessionGUID() {
return (S4()+S4());
}
function S4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
It clearly returns a string, but if you run it a bunch of times, you can notice that it sometimes returns infinity.
for (var i = 0; i < 100000; i++){ if(getSessionGUID() == Infinity) console.log("INFINITY"); }
871 x INFINITY
I then noticed that if you remove the |0, it solves the problem:
function S4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
}
Results:
for (var i = 0; i < 100000; i++){ if(getSessionGUID() == Infinity) console.log("INFINITY"); }
undefined
Why does this happen? In both cases the value is changed into a string.
Upvotes: 1
Views: 719
Reputation: 46728
JavaScript is dynamically typed. There isn't an integer, floating point. String data type. All of that conversions is done internally depending on the context.
The + could be string concatenation or addition depending on context.
Edit: Apologies. Too late. But it was the == performing the conversion to number when comparing against infinity. In some cases, you generated valid numbers.
Upvotes: 2
Reputation: 46647
You are generating hexidecimal strings.
When you use the ==
operator, the interpreter tries to coerce the two values to the same data type. When comparing strings to Infinity
, that intermediate data type is Number
. When those strings contain the letter "e" (a valid hexidecimal digit) and they're coerced to a Number
, javascript interprets this as 10^x which ends up as some huge number.
Number
s in javascript are 8 bytes, so anything larger than 1.7976931348623157e308
is considered equal to Infinity
.
The easiest way to fix this is to change your ==
to ===
so the string doesn't get coerced to a number.
if(getSessionGUID() === Infinity)
Upvotes: 3
Reputation: 27287
This test reveals the answer:
for (var i = 0; i < 100000; i++){
var x=getSessionGUID();
if(x == Infinity) console.log(x); }
}
It logs values like 61e93284
or 1413e390
These values are valid numbers and they are way too big for the Number type, so they get cast as Infinity when interpreted as a number.
If you replace ==
with ===
in the test, no conversion occurs and nothing is logged. The conversion is caused by the ==
operator.
Upvotes: 2
Reputation: 1117
I think I figured it out. There's actually nothing wrong in all of this, except on my test code.
If you take this string "11e51354", you can get it to assert to true since Javascript checks for all the types that could make it equal to true.
"11e51354" == Infinity # True
The right test would be:
"11e51354" === Infinity # False
It's still a string, but somehow while I was sending it through a GET request, it was being transformed into a number type which gave Infinity.
Upvotes: 2
Reputation: 13843
If you really need a number type, you always could use following.
console.log(Number("1"));
Upvotes: 0