At one point or another, while using JS, you should have encounter the limitation of number encoding. The most infamous example is:
0.1 + 0.2 === 0.3 // => false
I'm not going to explain it here, because I don't understand it fully myself. But you should know that storing infinite precision numbers over finite memory is not possible.
Math.PI // => 3.141592653589793 "only" 16 digits long.
As it can lack precision for small number, it's also true for large numbers. As soon as you go higher than
2^53 - 1, you're subject to error.
Number.MAX_SAFE_INTEGER // => 9007199254740991 Number.MAX_SAFE_INTEGER + 2 // => 9007199254740992 (1 + 2 = 2 ?)
It can get even worse if your integer goes beyond
2^1024 - 1, because JS will treat it as
Number.MAX_VALUE // => 1.7976931348623157e+308 Number.MAX_VALUE * 2 // => Infinity 1.8e308 // => Infinity
It's extremely easy to use, just add a
n character in the end of your numbers.
99 ** 999 // => Infinity 99n ** 999n // => 436073206168265161501341703386462012231079860756206...
If you can't add the
n, like when you consume the result of a function, you can wrap it in a constructor.
BigInt(getNumberViewers()) * BigInt(getAverageWatchDuration())
There's a few thing to remember while using BigInts.
First, BigInts are not compatible with regular numbers. So, you need to transform all operand to one or the other when doing maths.
const bigInt = 99n ** 999n; bigInt * 10 // => TypeError: Cannot mix BigInt and other types
Secondly, BigInts are not compatible with
Math. Only basic maths operation are allowed.
Math.max(10n, 20n) // => TypeError: Cannot convert a BigInt value to a number 10n < 20n // => true
Thirdly, while division are supported, they automatically round to the closest to 0 integer.
19n / 10n // => 1n -19n / 10n // => -1n
Finally, you'll have to consider that BigInt are a bit more ressource consuming than native numbers. So you should be using them only when manipulating ever growing numbers, like timestamps, users actions ...
Until next time, peace ✌️