Javascript: To Infinity and Beyond!
I don't often read or write software written in Javascript. However, I recently stumbled upon GitHub user KibaeKim's SectorTradingAlgorithm. It was advertised as performing with an ~24.85% annualized return, and the code was small and well-written enough that I started idly scanning through it. It didn't take long before I noticed the author using NEGATIVE_INFINITY to initialize a variable aimed at tracking the best performing ETF for that day.
This was the first time I had seen the Number.NEGATIVE_INFINITY
constant, and my curiosity was piqued. A brief look at the MDN Infinity documentation reveals some general information, as well as a fair amount of "what the hell, Javascript" moments as I learned about some of the weirder quirks of the constant. For instance, it was not actually constant (aka read-only) until ES5.
However, the thing that grabbed my attention the most is the first line of the documentation: "The global property Infinity
is a numeric value representing infinity." Wait...numeric? How does that work? If the property itself is numeric, how could you tell it apart from other numeric values? In other words, what numeric value could you assign to an Infinity
constant that would be indistinguishable during runtime from the actual equivalent numeric value? So, onward...to infinity, and beyond!
Consulting the Console
My first attempt to better understand Infinity
values was to open up a console. I'm using Firefox 89.0, and a quick glance at Number.POSITIVE_INFINITY
revealed that it is a Number
object, and doesn't look too different from any other Number
, constant or otherwise:
var infinity = Number.POSITIVE_INFINITY;
var max_value = Number.MAX_VALUE;
console.log(infinity.__proto__);
console.log(max_value.__proto__);
I'll save you the output, both are Object
prototypes of the class Number
, and don't appear to do anything special. However, poking at the methods, I discovered that the valueOf()
function for infinity
returns...uh, Infinity
?
The Search for Infinity
Heading back over to the MDN docs for Infinity, I came across this description: "Infinity
is a property of the global object. In other words, it is a variable in global scope." I feel like this is probably the eureka moment I'm looking for, but unfortunately I have no idea what the global object is. A couple more clicks of the keyboard landed me on the docs for Global Object. Here's the relevant portion:
In JavaScript, there's always a global object defined [...] thewindow
object is the Global Object in the Browser. Any Global Variables or Functions can be accessed as properties of thewindow
object.
Alright, so Infinity
is some property of the global object, aka window
. It's starting to make a bit more sense, and we hop back over to the console to confirm that the window
object does indeed have an infinity
property, set to Infinity
:
console.log(window.infinity);
> Infinity
The source of Infinity
has been tracked down! The Number
constants refer to either positive or negative Infinity
, which is a property of the global object. But I still don't understand what Infinity
is under-the-hood. We can easily find out via window.infinity.__proto__
that it's just another Number
object. But I'm still interested in what it's value is and how it's represented.
The Value of Infinity
To push this investigation along, I decided to take a look at the place where Infinity
was first defined: ECMAScript, first edition. We can find the PDF for this specification via ECMA International, and it's like cracking open a piece of history. Inside, we get some more information about it's implementation:
The Number type has exactly [...] 264−253+3 values, representing the double-precision 64-bit format IEEE 754 values as specified in the IEEE Standard for Binary Floating-Point Arithmetic, except [...] there are two other special values [aside from NaN], called positive Infinity and negative Infinity.
So, then, it seems all numbers in Javascript are represented as 64-bit IEEE 754 floating point numbers. There are a few values reserved in the ECMAScript specification to represent NaN
, as well as positive and negative Infinity
. This seems to indicate that the Infinity
values are actually a part of the IEEE 754 specification. And, digging into that specification, I learned that numbers are represented by three sections of bits: one bit for the sign, eleven bits for the exponent and fifty-two bits for the fraction. In the case of Infinity
, IEEE 754 specifies that the sign is treated as normal, the eleven bits representing the exponent are all set and the fraction bits are all unset. We have found our answer!
The Sum(mary) of Infinity
After doing more research than I expected, I've learned that the Number.POSITIVE_INFINITY
and Number.NEGATIVE_INFINITY
values reference the Infinity
primitive defined in the global object. The actual value of this property is defined by IEEE 754, in which positive Infinity
is represented by the binary value 0111111111110000000000000000000000000000000000000000000000000000
, and negative Infinity
is the same value but with the initial bit flipped to 1
. I'm infinitely positive that I will never use this knowledge in my career. Thanks for reading!