I would expect the number that I pass to BigInt has already overflowed before the BigInt creation, yet the result is correct. What is the reason, and can I rely on this for other powers of 2 (my use case)?
That is because the JavaScript number
type follows the IEEE 754 standard for floating point numbers. These numbers are stored like this:
+1
)100
).0
)... to represent a number like sign * (1 + fractional part) * 2 ** exponent
. In your case, that number is +1 * (1 + .0) * 2 ** 100
.
You can see that it can store powers of two exactly.
You can't completely depend on it, though. This format is fixed size and so can only represent a finite number of numbers. The largest power of two that can be represented is 2 ** 1023
. Trying to do BigInt(2 ** 1024)
will throw a RangeError
, because floating point numbers that are too large to be represented in 64 bits are represented with a special Infinity
value.
You are not going to get an inexact value, though, if that's the most important aspect for you.
Should you need to deal with larger values, I suggest storing the exponent as a number and then doing 2n ** BigInt(my_exponent)
when you need the BigInt. (Or BigInt(2) ** BigInt(my_exponent)`).