There is a maximum safe integer in JavaScript

Just in case you didn’t know: all numbers in JavaScript are represented as doubles, or double-precision floating-point format to be very exact. Every number being a floating point number can sometimes cause subtle problems. One problem is representing large integers.

The largest integer JavaScript can “safely” represent as a number is 9,007,199,254,740,991 or 2^53 - 1. (This is also available as a static property on Number: Number.MAX_SAFE_INTEGER.) This is not as high as one might expect if one isn’t already familiar with binary64 numbers. One can test a number to see if it’s still “safe” to use with Number.isSafeInteger().

The reason the numbers are considered “unsafe” is because doing arithmetic or comparisons with the number will yield unexpected results. Once a number has grown above the point of safety, that number can never be trusted again. Here is an example:

const a = Number.MAX_SAFE_INTEGER + 1000
const b = a - Number.MAX_SAFE_INTEGER

b === 1000 // false

We would expect Number.MAX_SAFE_INTEGER + 1000 - Number.MAX_SAFE_INTEGER to be 1000 if the world made sense, but sadly it doesn’t. Once a number has crossed the “safe” threshold, it can’t ever be trusted again, even if one tries to subtract it back down into the safe range.

Also, and amazingly, this simple test will evaluate as true:

Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2 // true

What can one do?

Well, there is a new BigInt type in JavaScript that one can use, but it only recently became available in Safari and the poly-fills are pretty heavy. So I can’t really recommend it unless you 100% know that your viewers are only going to be using the latest and greatest OS versions.

The other option is to try to never let the numbers get too large by capping them and/or testing for safety where needed. This is what I generally do.

Good luck and I hope you learned something.