Update 2014-02-08: Follow-up blog post “What are integers in JavaScript?”

JavaScript can only safely represent integers i in the range −253 < i < 253. This blog post examines why that is and what “safely represent” means. It is based on an email by Mark S. Miller to the es-discuss mailing list.

Safe integers

The idea of a safe integer is about how mathematical integers are represented in JavaScript.

In the range (−253, 253) (excluding the lower and upper bounds), JavaScript integers are safe: there is a one-to-one mapping between mathematical integers and their representations in JavaScript.

Beyond this range, JavaScript integers are unsafe: two or more mathematical integers are represented as the same JavaScript integer. For example, starting at 253, JavaScript can only represent every second mathematical integer.

> Math.pow(2, 53) 9007199254740992 > Math.pow(2, 53)+1 9007199254740992 > Math.pow(2, 53)+2 9007199254740994 > Math.pow(2, 53)+3 9007199254740996 > Math.pow(2, 53)+4 9007199254740996 > Math.pow(2, 53)+5 9007199254740996 > Math.pow(2, 53)+6 9007199254740998

mantissa × 2exponent

Why is that? Simplifyingly, a number in JavaScript is represented asMantissa and exponent give you 53 bit integers (consult [1] for the details). But you can represent higher integers by using higher exponents. For example, the 53 bit range of integers with an exponent incremented by one (a multiplication by two) becomes a 54 bit range. However, now only every second integer can be represented, as we have seen above.

Similarly, starting at 254, JavaScript can only represent every fourth mathematical integer (and so on).

> Math.pow(2, 54) 18014398509481984 > Math.pow(2, 54)+1 18014398509481984 > Math.pow(2, 54)+2 18014398509481984 > Math.pow(2, 54)+3 18014398509481988 > Math.pow(2, 54)+4 18014398509481988

Definitions in ECMAScript 6

Number.MAX_SAFE_INTEGER = Math.pow(2, 53)-1; Number.MIN_SAFE_INTEGER = -Number.MAX_SAFE_INTEGER;

Number.isSafeInteger = function (n) { return (typeof n === 'number' && Math.round(n) === n && Number.MIN_SAFE_INTEGER <= n && n <= Number.MAX_SAFE_INTEGER); }

n

n

n

MIN_SAFE_INTEGER

MAX_SAFE_INTEGER

Safe results of arithmetic computations

> 9007199254740990 + 3 9007199254740992

> Number.isSafeInteger(9007199254740990) true > Number.isSafeInteger(3) true > Number.isSafeInteger(9007199254740992) false

> 9007199254740995 - 10 9007199254740986

> Number.isSafeInteger(9007199254740995) false > Number.isSafeInteger(10) true > Number.isSafeInteger(9007199254740986) true

op

isSafeInteger(a) && isSafeInteger(b) && isSafeInteger(a op b)

a op b

Recommended reading

Therefore, a safe JavaScript integer is one that unambiguously represents a single mathematical integer.ECMAScript 6 will probably provide the following constants:It will also provide a function for determining whether an integer is safe:For a given value, this function first checks whetheris a number and whether it is an integer. If both checks succeed,is safe if it is greater or equal toand less or equal toHow can we make sure that results of arithmetic computations are correct? For example, the following result is clearly not correct.We have two safe operands, but an unsafe result:The following result is also incorrect:This time, the result is safe, but one of the operands isn’t:Therefore, the result of applying an integer operatoris only guaranteed to be correct if all operands and the result are safe. More formally:implies thatis a correct result.This blog post is part of a series of posts on JavaScript’s numbers.