Skip to main content

JavaScript Numbers & Math

JavaScript Integer Safety

Written by Published

JavaScript numbers are only exact up to a certain size, after which BigInt takes over.

The limit is about nine quadrillion.

Beyond it, whole numbers stop being reliable.

Example

Example

javascript

console.log(Number.MAX_SAFE_INTEGER);
console.log(Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2);

The second line is true, which should be impossible.

Past the safe limit, different numbers can compare as equal.

Safe Integers

Number.MAX_SAFE_INTEGER is the largest exact whole number.

Number.isSafeInteger checks whether a value is inside the limit.

BigInt handles whole numbers of any size.

Syntax

Syntax

javascript

Number.isInteger(value);
BigInt(value);

A BigInt literal ends with n.

Checking for a Whole Number

isInteger is true only for exact whole numbers.

Example

Example

javascript

console.log(Number.isInteger(42));
console.log(Number.isInteger(42.0));
console.log(Number.isInteger(42.5));

42.0 is stored as 42, so it counts as an integer.

Safe Versus Unsafe

Beyond the limit the arithmetic silently stops being exact.

Example

Example

javascript

console.log(Number.isSafeInteger(9007199254740991));
console.log(Number.isSafeInteger(9007199254740993));

The output is true then false.

BigInt for Large Values

Adding n makes a BigInt, which stays exact.

Example

Example

javascript

const big = 9007199254740991n;

console.log(big + 1n === big + 2n);
console.log(typeof big);

Now the comparison is false, as it should be.

BigInt Does Not Mix

You cannot add a BigInt to an ordinary number.

Convert one side first.

Example

Example

javascript

const big = 10n;
let message;

try {
  const result = big + 5;
} catch (error) {
  message = "cannot mix BigInt and Number";
}

console.log(message);
console.log(big + BigInt(5));

Mixing them throws a TypeError.

When It Matters

Most programs never come close to the limit.

It matters for database ids, timestamps in nanoseconds, and large financial values.

Example

Example

javascript

const id = 9007199254740993;

console.log(Number.isSafeInteger(id) ? "safe" : "use a string or BigInt");

Large ids from an API are often sent as strings for this reason.

Complete Example

Complete Example

html

<!DOCTYPE html>
<html>
<head>
  <title>JavaScript Integer Safety</title>
</head>
<body>

  <h1>Integer Safety</h1>

  <p id="out"></p>

  <script>
    const limit = Number.MAX_SAFE_INTEGER;

    document.getElementById("out").innerHTML =
      "Largest safe integer: " + limit +
      "<br>Beyond it, +1 equals +2: " + (limit + 1 === limit + 2) +
      "<br>With BigInt: " + (BigInt(limit) + 1n === BigInt(limit) + 2n) +
      "<br>Is 42.5 an integer: " + Number.isInteger(42.5);
  </script>

</body>
</html>

Try It Yourself

Run the above example in the Try It Editor.

Try the limit itself:

Check Number.isSafeInteger(limit) and then limit + 2.

Important Points

  • Whole numbers are exact up to MAX_SAFE_INTEGER.
  • Beyond it, different values can compare as equal.
  • Number.isInteger checks for a whole number.
  • BigInt handles any size exactly.
  • BigInt and Number cannot be mixed in arithmetic.

Conclusion

Most code never reaches the safe integer limit.

When it does, the failure is silent, which makes it dangerous.

Large ids are usually passed around as strings to avoid the problem entirely.