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

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

+/- 9007199254740991

ECMA Section 8.5 – Numéros

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

Ce sont des valeurs de virgule flottante à 64 bits, la plus grande valeur intégrale exacte est 2 53 -1 ou 9007199254740991 . Dans ES6, cela est défini comme Number.MAX_SAFE_INTEGER .

Notez que les opérateurs bit à bit et les opérateurs à décalage opèrent sur des entrées de 32 bits, donc, dans ce cas, l'entier maximum sécurisé 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 

De la référence :

 alert([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 

C'est 2 53 == 9 007 199 254 740 992. C'est parce que le Number s est stocké en virgule flottante dans une mantisse 52 bits.

La valeur min est de -2 53 .

Cela fait des choses amusantes qui se passent

 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 } 

Autres lectures: http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html

En javascript, il y a un nombre appelé Infinity

exemples:

 (Infinity>100) => true //also worth noting Infinity - 1 == Infinity => true Math.pow(2,1024) === Infinity => true 

Cela peut être suffisant pour certaines questions concernant ce sujet.

La réponse de Jimmy représente correctement le spectre entier en ligne continu comme -9007199254740992 à 9007199254740992 inclus (désolé 9007199254740993, vous pourriez penser que vous êtes 9007199254740993, mais vous avez tort! ).

Cependant, il n'y a pas de réponse qui trouve / prouve ceci par programmation (autrement que le CoolAJ86 mentionné dans sa réponse qui finirait en 28,56 ans;), alors voici un moyen légèrement plus efficace de le faire (précisément, c'est plus efficace Vers 28,559999999968312 ans :), avec un violon à tester :

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

Pour être sûr

 var MAX_INT = 4294967295; 

Raisonnement

Je pensais être intelligent et trouver la valeur à laquelle x + 1 === x avec une approche plus pragmatique.

Ma machine ne peut compter que 10 millions par seconde environ … alors je vais poster avec la réponse définitive en 28,56 ans.

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

  • La plupart de vos boucles ne fonctionnent pas pour 28,56 ans
  • 9007199254740992 === Math.pow(2, 53) + 1 est une preuve suffisante
  • Vous devez vous en tenir à 4294967295 qui est Math.pow(2,32) - 1 afin d'éviter les problèmes attendus avec le décalage de bit

Trouver 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); }()); 

ECMAScript 6:

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

La réponse courte est "cela dépend".

Si vous utilisez des opérateurs bit à bit n'importe où (ou si vous faites référence à la longueur d'une matrice), les plages sont:

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

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

(Il se trouve que les opérateurs bit à bit et la longueur maximale d'un tableau sont limités à des entiers 32 bits.)

Si vous n'utilisez pas d'opérateurs bit à bit ou que vous utilisez 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 "Nombre", 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 la grandeur de la limite positive, en raison des caractéristiques de la représentation interne, qui inclut réellement un négatif 0!)

D'autres ont déjà donné la réponse générique, mais je pensais 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 évalue les pouvoirs de 2 pour trouver celui qui, lorsqu'il est «ajouté» 1, est égal à lui-même.

Tout ce que vous souhaitez utiliser pour les opérations bit à 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 et 0x80000000 est égal à -2147483648

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

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

MaxInt = -1 >>> 1

Dans Firefox 3.6 c'est 2 ^ 31 – 1.

Je l'écris comme ceci:

 var max_int = 0x20000000000000; var min_int = -0x20000000000000; (max_int + 1) === 0x20000000000000; //true (max_int - 1) < 0x20000000000000; //true 

Idem pour int32

 var max_int32 = 0x80000000; var min_int32 = -0x80000000; 

Dans le javascript incorporé Google Chrome, vous pouvez aller à environ 2 ^ 1024 avant que le nombre ne soit appelé l'infini.

Scato wrotes:

Tout ce que vous souhaitez utiliser pour les opérations bit à 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 et 0x80000000 est égal à -2147483648

Hex-Decimals sont des valeurs positives non signées, donc 0x80000000 = 2147483648 – c'est mathématiquement correct. Si vous voulez faire une valeur signée, vous devez revenir à droite: 0x80000000 >> 0 = -2147483648. Vous pouvez écrire 1 << 31 à la place, aussi.

Number.MAX_VALUE représente la valeur numérique maximale représentable en JavaScript.

Comme personne ne semble l'avoir dit, dans le moteur v8 , il y a une différence de comportement pour un nombre de 31 bits et un nombre supérieur à celui-ci.

Si vous avez 32 bits vous pouvez utiliser le premier bit pour indiquer au moteur javascript quel type de données est et les bits restants contiennent les données réelles. C'est ce que V8 fait comme une petite optimisation pour les numbers 31 bis (ou l'habitude de le faire, mes sources sont assez dattes). Vous avez les 31 bits derniers 31 bits étant la valeur numérique, puis le premier bit indiquant le moteur s'il s'agit d'un numéro ou d'une référence d'objet.

Toutefois, si vous utilisez le numéro supérieur à 31 bits les données ne correspondent pas, le nombre sera encapsulé en 64 bits et l'optimisation ne sera pas là.

La ligne de fond, dans la vidéo ci-dessous, est:

Préfèrent les valeurs numériques qui peuvent être représentées sous forme de nombres entiers signés 31bits .

  • Vidéo intéressante
  • Autre source

Firefox 3 ne semble pas avoir de problème avec d'énormes nombres.

1e + 200 * 1e + 100 calculera bien à 1e + 300.

Safari semble ne pas avoir de problème avec lui aussi. (Pour mémoire, c'est sur un Mac si quelqu'un d'autre décide de tester cela)

À moins d'avoir perdu mon cerveau à cette heure-ci, c'est beaucoup plus grand qu'un entier de 64 bits.

MISE À JOUR: Node.js et google Chrome semblent tous deux utiliser des valeurs de virgule flottante de 1024 bits, donc:

Number.MAX_VALUE = 1.7976931348623157e+308