21

I'm reading the second chapter of the book Eloquent JavaScript. The author states that:

Any whole number less than 2^52 (which is more than 10^15) will safely fit in a JavaScript number.

I grabbed the value of 2^52 from wikipedia.

4,503,599,627,370,496

The value has to be less than 2^52, so I've substracted 1 from the initial value;

var max = 4503599627370495;

After defining the max variable I'm checking what's the value (I'm using Chrome 32.0.1700.77).

console.log(max); // 4503599627370495

I'd like to see what happens when I go over this limit, so I'm adding one a couple of times.

Unexpectedly:

max += 1;
console.log(max); // 4503599627370496
max += 1;
console.log(max); // 4503599627370497
max += 1;
console.log(max); // 4503599627370498

I went over the limit and the calculations are still precise.

I tried the next power of two instead, 2^53, I didn't substract 1 this time:

9,007,199,254,740,992

var max = 9007199254740992;

This one seems to be a bigger limit, it seems that I can quite safely add and substract numbers:

max += 1;
console.log(max); // 9007199254740992
max += 1;
console.log(max); // 9007199254740992
max -= 1;
console.log(max); // 9007199254740991
max += 1;
console.log(max); // 9007199254740992
max -= 900;
console.log(max); // 9007199254740092
max += 900;
console.log(max); // 9007199254740992

I can assign even a bigger value to the max, however it loses precision and I can't safely add or substract numbers again.

Could you please explain precisely the mechanism that sits under the hood? An example of what happens with the bits after going above 2^52 would be really helpful.

1

3 Answers 3

12

This is not a strongly typed programming language. JS has an object Number. You can even get an infinite number: document.write(Math.exp(1000));.

document.write(Number.MIN_VALUE + "<br>");
document.write(Number.MAX_VALUE + "<br>");

document.write(Number.POSITIVE_INFINITY + "<br>");
document.write(Number.NEGATIVE_INFINITY + "<br>");

    alert([
         Number.MAX_VALUE/(1e293),
         Number.MAX_VALUE/(1e292),
         Number.MAX_VALUE/(1e291),
         Number.MAX_VALUE/(1e290),
    ].join('\n'))

Hope it's a useful answer. Thanks!

UPDATE: max int is - +/- 9007199254740992

Sign up to request clarification or add additional context in comments.

Comments

8

You can find some information on JavaScript's Number type here: ECMA-262 5th Edition: The Number Type.

As it mentions, numbers are represented as a 64-bit floating-point number, with 53 bits of mantissa (significant digits) and 11 bits for the exponent (IEEE 754). The result is then obtained with: mantissa * 2^exponent.

This means that up to 2^53 values can be represented in the mantissa (of those a few numbers have special meanings, and the others are positive and negative integers).

The number 2^53 (9007199254740992) can't be represented in the mantissa, and you have to use an exponent. As an example, you can represent 2^53 as (9007199254740992 / 2) * 2^1, ie. mantissa = 9007199254740992 / 2 = 4503599627370496 and exponent = 1.

Let's check what happens with 2^53+1 (9007199254740993). Here we have to do the same, mantissa = 9007199254740993 / 2 = 4503599627370496. Oops, isn't this the same mantissa we had for 2^53? Looks like there's been some rounding error! :)

(Note: the above examples are not actually how it really works: the mantissa is always interpreted as having a dot after the first digit, which means that eg. the number 3 is actually stored as 1.5*2. I omitted this in the above explanation to make it easier to follow.)

You can find some more information on floating-point numbers (in general) here: What Every Computer Scientist Should Know About Floating-Point Arithmetic.

Comments

3

You can think of 52 bits integer in JS, but remember that bitwise logical operators & | >> etc.. will only deal with 32 less significant bits discarding the rest.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.