Question Quelle est la valeur entière la plus élevée de JavaScript qu'un nombre peut atteindre sans perdre de précision?


Est-ce défini par la langue? Y a-t-il un maximum défini? Est-ce différent dans différents navigateurs?


798
2017-11-20 22:47


origine


Réponses:


+/- 9007199254740991

ECMA Section 8.5 - Numéros

Notez que tous les entiers positifs et négatifs dont la magnitude n'est pas supérieure à 253 sont représentables dans le type Number (en effet, l'entier 0 a deux représentations, +0 et -0).

Ce sont des valeurs à virgule flottante 64 bits, la plus grande valeur intégrale exacte est 253-1, ou 9007199254740991. En ES6, ceci est défini comme Number.MAX_SAFE_INTEGER.

Notez que les opérateurs bit à bit et les opérateurs de décalage fonctionnent sur des nombres de 32 bits, donc dans ce cas, l'entier de sécurité maximal est 2.31-1 ou 2147483647.


Testez-le!

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 le référence: 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



C'est 253 == 9 007 199 254 740 992. C'est parce que Numbers sont stockés en tant que point flottant dans une mantisse de 52 bits.

La valeur minimale est -253.

Cela rend les choses amusantes qui se passe

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

Et peut aussi être dangereux :)

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
}

En lire plus: http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html


101
2017-12-07 10:40



En JavaScript, il y a un numéro appelé Infinity.

Exemples:

(Infinity>100)
=> true

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

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

Cela peut suffire pour certaines questions concernant ce sujet.


53
2018-01-20 21:42



La réponse de Jimmy représente correctement le spectre entier continu JavaScript comme -9007199254740992 à 9007199254740992 inclusivement (désolé 9007199254740993, vous pourriez penser que vous êtes 9007199254740993, mais vous avez tort!   Démonstration ci-dessous ou dans jsfiddle).

document.write(9007199254740993);

Cependant, il n'y a pas de réponse qui trouve / prouve ceci par programme (autre que celle mentionnée dans CoolAJ86 dans sa réponse cela finirait dans 28,56 ans;), donc voici une façon un peu plus efficace de le faire (pour être précis, il est plus efficace d'environ 28.559999999968312 ans :), avec un tester le violon:

/**
 * 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



Pour être sûr

var MAX_INT = 4294967295;

Raisonnement

Je pensais que je serais intelligent et trouver la valeur à laquelle x + 1 === x avec une approche plus pragmatique.

Ma machine ne peut compter que 10 millions par seconde ... alors je posterai la réponse définitive dans 28,56 ans.

Si vous ne pouvez pas attendre si longtemps, je suis prêt à parier que

  • La plupart de vos boucles ne fonctionnent pas pendant 28,56 ans
  • 9007199254740992 === Math.pow(2, 53) + 1 est une preuve suffisante
  • Tu devrais rester 4294967295 lequel est Math.pow(2,32) - 1 pour éviter les problèmes attendus avec le décalage de bits

Découverte 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 réponse courte est "ça dépend".

Si vous utilisez des opérateurs au niveau du bit n'importe où (ou si vous faites référence à la longueur d'un tableau), les plages sont les suivantes:

Non signé: 0…(-1>>>0)

Signé: (-(-1>>>1)-1)…(-1>>>1)

(Il arrive que les opérateurs au niveau du bit et la longueur maximale d'un tableau sont limités à des entiers de 32 bits.)

Si vous n'utilisez pas d'opérateurs au niveau du bit ou si vous travaillez avec des longueurs de tableau:

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

Ces limitations sont imposées par la représentation interne du type "Number", qui correspond généralement à la représentation en virgule flottante double précision IEEE 754. (Notez que contrairement aux entiers signés typiques, l'amplitude de la limite négative est la même que l'amplitude de la limite positive, en raison des caractéristiques de la représentation interne, qui comprend en fait un négatif 0!)


27
2017-07-17 07:13



D'autres ont peut-être déjà donné la réponse générique, mais j'ai pensé que ce serait une bonne idée de donner un moyen rapide de le déterminer:

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

Ce qui me donne 9007199254740992 en moins d'une milliseconde dans Chrome 30.

Il va tester les pouvoirs de 2 pour trouver lequel, quand 'ajouté' 1, est égal à lui-même.


11
2017-10-05 16:53



Tout ce que vous voulez utiliser pour les opérations au niveau du bit doit être compris entre 0x80000000 (-2147483648 ou -2 ^ 31) et 0x7fffffff (2147483647 ou 2 ^ 31 - 1).

La console vous dira que 0x80000000 est égal à +2147483648, mais 0x80000000 & 0x80000000 est égal à -2147483648.


6
2018-05-15 07:53



J'ai fait un test simple avec une formule, X- (X + 1) = - 1, et la plus grande valeur de X que je peux utiliser sur Safari, Opera et Firefox (testé sur OS X) est 9e15. Voici le code que j'ai utilisé pour tester:

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

3
2017-11-20 23:21