As it specified in the BigInt
spec:
The value may be any size and is not limited to a particular bit-width
As it specified in the String
spec:
The String type is the set of all ordered sequences of zero or more 16-bit unsigned integer values ("elements") up to a maximum length of
2^53 - 1
elements
As it specified in the BigInt.toString
spec 2nd point:
Return the String value consisting of the representation of
x
using radix
However, a string with this length (
2^53 - 1
elements) needs16384TiB
of storage, which cannot fit in any reasonable device's memory, so implementations tend to lower the threshold, which allows the string's length to be conveniently stored in a 32-bit integer
So imagine that I have enough memory/time/cpu and so on. What will I get when run BigInt.toString()
if the BigInt
is too large and it takes more than 2^53 - 1
elements to return the String value?
V8 developer here (who, among other things, implemented BigInts).
What will I get when run BigInt.toString() if the BigInt is too large...
A RangeError
. (Or, potentially, an OOM crash, depending on the implementation details of your JS engine.)
As of today, V8 (and hence Chrome, Node, Opera, Edge, ...) limits BigInts to 2**30
bits (and we have no plans to raise that; in fact we think this limit is already higher than it needs to be). AFAIK Firefox limits them to 2**20
bits (which seems to be more than enough for practical purposes). Trying to create bigger BigInts than that produces a RangeError
.
Strings also have a maximum length in implementations, which is lower than the theoretical limit in the spec. In V8, depending on version/configuration/platform, the maximum string length is either 2**28
or 2**29
or 2**30
. Trying to create longer strings than that (by converting a BigInt, or by any other means) produces a RangeError
.
...and it takes more than
2^53 - 1
elements to return the String value?
As commenters have pointed out, this part of the question is indeed an entirely theoretical question for the foreseeable future. Before the 2**53 - 1
theoretical string length limit can become a practical limit, we'll need an entirely new generation of computer architecture definitions.
Current "64-bit" software architectures (x86_64, aarch64) are actually limited to 48-bit virtual memory addresses. They can't address more than 2**48
bytes (256 TB) of memory (from an application's perspective), and they reserve half of that address space for the kernel.
Current (consumer-grade) hardware is typically limited to anywhere between about 35 and 48 bits for physical addresses.
So even if you could buy an actual machine with 256 TB of memory, and you found (or implemented) a JS engine with sufficiently high internal limits, and you filled your entire memory with a single BigInt, then that BigInt's base-2 string representation would still have a length of "only" 2**50
-- but of course, you wouldn't be able to allocate that string, because all your memory is already occupied by that BigInt; and even if (for the sake of argument) you networked a second machine with just as much memory just to hold the string, then you could only store 2**47
string characters in 2**47
bytes of non-kernel application memory (assuming your JS engine has a one-byte string optimization), and above that you'd either get a RangeError
or an OOM crash depending on the implementation details of your engine.