Pregunta ¿Cuál es el valor entero más alto de JavaScript al que puede acceder un número sin perder precisión?


¿Esto está definido por el idioma? ¿Hay un máximo definido? ¿Es diferente en diferentes navegadores?


798
2017-11-20 22:47


origen


Respuestas:


+/- 9007199254740991

ECMA Sección 8.5 - Números

Tenga en cuenta que todos los enteros positivos y negativos cuya magnitud no es mayor que 253 son representables en el tipo Número (de hecho, el entero 0 tiene dos representaciones, +0 y -0).

Son valores de coma flotante de 64 bits, el valor integral exacto más grande es 253-1, o 9007199254740991. En ES6, esto se define como Número.MAX_SAFE_INTEGER.

Tenga en cuenta que los operadores en modo bit y los operadores de desplazamiento operan en entradas de 32 bits, por lo que en ese caso, el entero seguro máximo es 231-1 o 2147483647.


Pruébalo!

var x = 9007199254740992;
var y = -x;
x == x + 1; // true !
y == y - 1; // also true !
// Arithmetic operators work, but bitwise/shifts only operate on int32:
x / 2;      // 4503599627370496
x >> 1;     // 0
x | 1;      // 1

727
2017-11-20 22:53



> = ES6: Number.MIN_SAFE_INTEGER; Number.MAX_SAFE_INTEGER;

<= ES5

De la referencia: Number.MAX_VALUE; Number.MIN_VALUE;

console.log('MIN_VALUE', Number.MIN_VALUE);
console.log('MAX_VALUE', Number.MAX_VALUE);

console.log('MIN_SAFE_INTEGER', Number.MIN_SAFE_INTEGER); //ES6
console.log('MAX_SAFE_INTEGER', Number.MAX_SAFE_INTEGER); //ES6


404
2017-11-20 22:52



Es 253 == 9 007 199 254 740 992. Esto es porque Numbers se almacenan como punto flotante en una mantisa de 52 bits.

El valor mínimo es -253.

Esto hace que pasen cosas divertidas

Math.pow(2, 53) == Math.pow(2, 53) + 1
>> true

Y también puede ser peligroso :)

var MAX_INT = Math.pow(2, 53); // 9 007 199 254 740 992
for (var i = MAX_INT; i < MAX_INT + 2; ++i) {
    // infinite loop
}

Otras lecturas: http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html


101
2017-12-07 10:40



En JavaScript, hay un número llamado Infinity.

Ejemplos:

(Infinity>100)
=> true

// Also worth noting
Infinity - 1 == Infinity
=> true

Math.pow(2,1024) === Infinity
=> true

Esto puede ser suficiente para algunas preguntas sobre este tema.


53
2018-01-20 21:42



La respuesta de Jimmy representa correctamente el espectro entero de JavaScript continuo como -9007199254740992 a 9007199254740992 incluido (lo siento 9007199254740993, usted puede pensar que es 9007199254740993, pero usted está equivocado!   Demostración a continuación o en jsfiddle)

document.write(9007199254740993);

Sin embargo, no hay respuesta que encuentre / pruebe esto programáticamente (aparte del CoolAJ86 aludido en su respuesta eso terminaría en 28.56 años;), así que aquí hay una manera un poco más eficiente de hacerlo (para ser más precisos, es más eficiente por aproximadamente 28.559999999968312 años :), junto con un violín de prueba:

/**
 * Checks if adding/subtracting one to/from a number yields the correct result.
 *
 * @param number The number to test
 * @return true if you can add/subtract 1, false otherwise.
 */
var canAddSubtractOneFromNumber = function(number) {
    var numMinusOne = number - 1;
    var numPlusOne = number + 1;
    
    return ((number - numMinusOne) === 1) && ((number - numPlusOne) === -1);
}

//Find the highest number
var highestNumber = 3; //Start with an integer 1 or higher

//Get a number higher than the valid integer range
while (canAddSubtractOneFromNumber(highestNumber)) {
    highestNumber *= 2;
}

//Find the lowest number you can't add/subtract 1 from
var numToSubtract = highestNumber / 4;
while (numToSubtract >= 1) {
    while (!canAddSubtractOneFromNumber(highestNumber - numToSubtract)) {
        highestNumber = highestNumber - numToSubtract;
    }
    
    numToSubtract /= 2;
}        

//And there was much rejoicing.  Yay.    
console.log('HighestNumber = ' + highestNumber);


37
2017-07-24 21:30



Para estar seguro

var MAX_INT = 4294967295;

Razonamiento

Pensé que sería inteligente y encontraría el valor al que x + 1 === x con un enfoque más pragmático.

Mi máquina solo puede contar 10 millones por segundo más o menos ... así que volveré a publicar con la respuesta definitiva en 28.56 años.

Si no puedes esperar tanto, estoy dispuesto a apostar que

  • La mayoría de tus bucles no se ejecutan durante 28.56 años
  • 9007199254740992 === Math.pow(2, 53) + 1 es prueba suficiente
  • Debes apegarte a 4294967295 cual es Math.pow(2,32) - 1 para evitar problemas esperados con el cambio de bit

Hallazgo x + 1 === x:

(function () {
  "use strict";

  var x = 0
    , start = new Date().valueOf()
    ;

  while (x + 1 != x) {
    if (!(x % 10000000)) {
      console.log(x);
    }

    x += 1
  }

  console.log(x, new Date().valueOf() - start);
}());

32
2017-08-24 17:29



ECMAScript 6:

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

28
2018-03-31 05:52



La respuesta corta es "depende".

Si está utilizando operadores bit a bit en cualquier lugar (o si se refiere a la longitud de una matriz), los rangos son:

No firmado: 0…(-1>>>0)

Firmado: (-(-1>>>1)-1)…(-1>>>1)

(Resulta que los operadores bit a bit y la longitud máxima de una matriz están restringidos a enteros de 32 bits).

Si no está utilizando operadores bit a bit o trabajando con longitudes de matriz:

Firmado: (-Math.pow(2,53))…(+Math.pow(2,53))

Estas limitaciones son impuestas por la representación interna del tipo "Número", que generalmente corresponde a la representación de coma flotante de precisión doble IEEE 754. (Tenga en cuenta que a diferencia de los enteros con signo típicos, la magnitud del límite negativo es la misma que la del límite positivo, debido a las características de la representación interna, que en realidad incluye una negativo 0!)


27
2017-07-17 07:13



Es posible que otros ya hayan dado la respuesta genérica, pero pensé que sería una buena idea dar una forma rápida de determinarlo:

for (var x = 2; x + 1 !== x; x *= 2);
console.log(x);

Lo que me da 9007199254740992 en menos de un milisegundo en Chrome 30.

Probará los poderes de 2 para encontrar cuál, cuando 'suma' 1, se iguala a sí mismo.


11
2017-10-05 16:53



Todo lo que desee utilizar para las operaciones en modo bit debe ser entre 0x80000000 (-2147483648 o -2 ^ 31) y 0x7fffffff (2147483647 o 2 ^ 31 - 1).

La consola le dirá que 0x80000000 es igual a +2147483648, pero 0x80000000 y 0x80000000 es igual a -2147483648.


6
2018-05-15 07:53



Hice una prueba simple con una fórmula, X- (X + 1) = - 1, y el mayor valor de X que puedo ponerme a trabajar en Safari, Opera y Firefox (probado en OS X) es 9e15. Aquí está el código que utilicé para probar:

javascript: alert(9e15-(9e15+1));

3
2017-11-20 23:21