Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding to Number.MAX_VALUE

The answer to this question may be painfully obvious but I can't find it in the Mozilla docs nor on Google from a cursory search.

If you have some code like this

Number.MAX_VALUE + 1; // Infinity, right?
Number.MIN_VALUE - 1; // -Infinity, right?

Then I would expect adding anything to Number.MAX_VALUE would push it over to Infinity. The result is just Number.MAX_VALUE spat right back at me.

However, when playing around in the Chrome JS console, I noticed that it didn't actually become Infinity until I added/subtracted enough:

Number.MAX_VALUE + Math.pow(100,1000); // now we hit Infinity
Number.MIN_VALUE - Math.pow(100,1000); // -Infinity at last

What is the explanation for this "buffer" between Number.MAX_VALUE and Infinity?

like image 966
Mark Avatar asked May 31 '12 16:05

Mark


People also ask

What is number MAX_VALUE in JavaScript?

JavaScript Number MAX_VALUE Number. MAX_VALUE returns the largest number possible in JavaScript. Number. MAX_VALUE has the value of 1.7976931348623157e+308.

What does integer MAX_VALUE return?

Integer. MAX_VALUE represents the maximum positive integer value that can be represented in 32 bits (i.e., 2147483647 ). This means that no number of type Integer that is greater than 2147483647 can exist in Java.

What is the maximum number value?

This number is the data value that is greater than or equal to all other values in our set of data. If we were to order all of our data in ascending order, then the maximum would be the last number listed. The maximum is a unique number for a given set of data.


2 Answers

Standardwise...

In ECMAScript, addition of two nonzero finite numbers is implemented as (ECMA-262 §11.6.3 "Applying the Additive Operators to Numbers"):

the sum is computed and rounded to the nearest representable value using IEEE 754 round-to-nearest mode. If the magnitude is too large to represent, the operation overflows and the result is then an infinity of appropriate sign.

IEEE-754's round-to-nearest mode specifies that (IEEE-754 2008 §4.3.1 "Rounding-direction attributes to nearest")

In the following two rounding-direction attributes, an infinitely precise result with magnitude at least bemax ( b − ½ b1-p ) shall round to ∞ with no change in sign; here emax and p are determined by the destination format (see 3.3). With:

  • roundTiesToEven, the floating-point number nearest to the infinitely precise result shall be delivered; if the two nearest floating-point numbers bracketing an unrepresentable infinitely precise result are equally near, the one with an even least significant digit shall be delivered
  • roundTiesToAway, the floating-point number nearest to the infinitely precise result shall be delivered; if the two nearest floating-point numbers bracketing an unrepresentable infinitely precise result are equally near, the one with larger magnitude shall be delivered.

ECMAScript does not specify which of the round-to-nearest, but it doesn't matter here because both gives the same result. The number in ECMAScript is "double", in which

  • b = 2
  • emax = 1023
  • p = 53,

so the result must be at least 21024 - 2970 ~ 1.7976931348623158 × 10308 in order to round to infinity. Otherwise it will just round to MAX_VALUE, because that is the closer than Infinity.

Notice that MAX_VALUE = 21024 - 2971, so you need to add at least 2971 - 2970 = 2970 ~ 9.979202 × 10291 in order to get infinity. We could check:

>>> Number.MAX_VALUE + 9.979201e291
1.7976931348623157e+308
>>> Number.MAX_VALUE + 9.979202e291
Infinity

Meanwhile, your Math.pow(100,1000) ~ 26643.9 is well beyond 21024 - 2970. It is already infinity.

like image 67
kennytm Avatar answered Oct 19 '22 08:10

kennytm


If you look at Number.MAX_VALUE.toString(2), you'll see that the binary representation of MAX_VALUE is 53 ones followed by 971 zeros. This because IEEE 754 floating points are made of a mantissa coefficient multiplied by a power of 2 (so the other half of the floating point number is the exponent). With MAX_VALUE, both the mantissa and the exponent are maxed out, so you see a bunch of ones bit-shifted up a lot.

In short, you need to increase MAX_VALUE enough to actually affect the mantissa, otherwise your additional value gets lost and rounded out.

Math.pow(2, 969) is the lowest power of 2 that will not tip MAX_VALUE into Infinity.

like image 35
apsillers Avatar answered Oct 19 '22 07:10

apsillers