## Dark Rock of Mothrir Unsealed: JavaScript has integers now.

@BrendanEich:

"BigInt has been shipped in Chrome and is underway in Node, Firefox, and Safari."

BigInt is a new primitive that provides a way to represent whole numbers larger than 253, which is the largest number Javascript can reliably represent with the Number primitive.

But the tragic historical fact that until now, all Javascript numbers were floats means that it's impossible to implement this backward-compatibly without significant syntactic warts:

Many (all?) other dynamically typed programming languages which have multiple numeric types implement a numeric tower. This forms an ordering between types -- on the built-in numeric types, when an operator is used with operands from two types, the greater type is chosen as the domain, and the "less general" operand is cast to the "more general" type. Unfortunately, as the previous example shows, there is no "more general" type between arbitrary integers and double-precision floats. The typical resolution, then, is to take floats as the "more general" type.

Silently losing precision sometimes may be a problem, but in most dynamically typed programming languages which provide integers and floats, integers are written like 1 and floats are written like 1.0. It's possible to scan code for operations which may introduce floating point precision by looking for a decimal point. JavaScript exacerbates the scope of losing precision by making the unfortunate decision that a simple literal like 1 is a float. So, if mixed-precision were allowed, an innocent calculation such as 2n ** 53n + 1 would produce the float 2 ** 53 -- defeating the core functionality of this feature.

To avoid this problem, this proposal bans implicit coercions between Numbers and BigInts, including operations which are mixed type. 1n + 1 throws a TypeError. So does passing 1n as an argument into any JavaScript standard library function or Web API which expects a Number. Instead, to convert between types, an explicit call to Number() or BigInt() needs to be made to decide which domain to operate in. 0 === 0n returns false.

That's all well and good, but obviously the burning questions that I want the answers to are, "What is MOST-POSITIVE-BIGNUM, and how long does it take the Javascript console to print it?"

I wasn't able to figure out which of the several BigInt Javascript packages out there most closely resemble this spec, nor was I able to figure out which of them is the one being used by Chrome. But I assume that they are all representing the bits of the BigInt inside an array (whose cells are either uint32 or IEEE-754 floats) which means that the gating factor is the range of the integer representing the length of an array (which by ECMA is 2^32-1). So the answer is probably within spitting distance of either 232(232) or 253(232).

As a first attempt, typing 10n ** 1223146n - 1n into Chrome's JS console made it go catatonic for a minute or so, but then it spat out a string of 1,223,147 nines. (Fortunately it truncated it rather than printing them all.) So that's bigger than the Explorer version!

> (2n ** 32n - 1n) ** (2n ** 32n - 1n)
× Uncaught RangeError: Maximum BigInt size exceeded
> (2n ** 32n - 1n) ** (2n ** 31n - 1n)
× Uncaught RangeError: Maximum BigInt size exceeded
> (2n ** 32n - 1n) ** (2n ** 30n - 1n)
... and maybe we have a winner, or at least a lower bound on the max?

That last one has made Chome sit there chewing four CPU-hours so far, so it's either still doing the exponentiation, or it's trying to grind it to decimal. If it ever comes back with a result, I'll update this post...

Update: After 87 hours, I stopped waiting.

## Front page New York Times, August 10, 1988.

xor: "I can't believe it's been 30 years since Zero Cool hacked all those banks across state lines"