Quelle est la valeur entière la plus élevée de JavaScript à laquelle un nombre peut aller sans perdre en précision?

951

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

TALlama
la source
5
Vous n'avez pas besoin de dépendre des limites de JS avec des bibliothèques comme github.com/MikeMcl/big.js , voir par exemple ici pour ses tests de fiabilité
Dmitri Zaitsev
2
quelle est la valeur entière la plus élevée que vous pouvez utiliser avec big.js?
George
@George Voici l'API big.js: mikemcl.github.io/big.js/#dp
simhumileco
La question n'a pas de sens. Qu'est-ce que cela signifie qu'un nombre "va" à une valeur entière? Si vous voulez simplement demander quel est le nombre entier le plus élevé que vous pouvez représenter dans JS, le nombre le plus élevé (fini) lui-même est un nombre entier.
Veky
@DmitriZaitsev Nous n'avons plus besoin de dépendre de bibliothèques externes (au moins sur certains navigateurs). 1n << 10000nest un très grand entier, sans perdre de précision, sans nécessiter de dépendances (et il va sans dire, même pas proche d'une limite).
Amadan

Réponses:

868

JavaScript a deux types de nombres: Numberet BigInt.

Le type de numéro le plus utilisé Number, est un nombre IEEE 754 à virgule flottante 64 bits .

La plus grande valeur intégrale exacte de ce type Number.MAX_SAFE_INTEGERest:

  • 2 53 -1, ou
  • +/- 9 007 199 254 740 991, ou
  • neuf quadrillions sept trillions cent quatre-vingt-dix-neuf milliards deux cent cinquante-quatre millions sept cent quarante mille neuf cent quatre-vingt-onze

Pour mettre cela en perspective: un quadrillion d'octets est un pétaoctet (ou mille téraoctets).

Dans ce contexte, "sûr" se réfère à la capacité de représenter exactement des nombres entiers et de les comparer correctement.

De la spécification:

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

Pour utiliser en toute sécurité des entiers supérieurs à celui-ci, vous devez utiliser BigInt, qui n'a pas de limite supérieure.

Notez que les opérateurs au niveau du bit et les opérateurs de décalage fonctionnent sur des entiers 32 bits, donc dans ce cas, l'entier maximal sûr est 2 31 -1, ou 2 147 483 647.

const log = console.log
var x = 9007199254740992
var y = -x
log(x == x + 1) // true !
log(y == y - 1) // also true !

// Arithmetic operators work, but bitwise/shifts only operate on int32:
log(x / 2)      // 4503599627370496
log(x >> 1)     // 0
log(x | 1)      // 1


Note technique au sujet du nombre 9,007,199,254,740,992: Il existe une représentation IEEE-754 exacte de cette valeur, et vous pouvez assigner et lire cette valeur à partir d'une variable, donc pour très attentivement applications choisies dans le domaine des entiers inférieurs ou égaux à cette valeur, vous pouvez la traiter comme une valeur maximale.

Dans le cas général, vous devez traiter cette valeur IEEE-754 comme inexacte, car il est ambigu qu'il s'agisse de coder la valeur logique 9,007,199,254,740,992 ou 9,007,199,254,740,993.

Jimmy
la source
75
Cela semble vrai, mais existe-t-il un endroit où cela est défini, à savoir MAX_INT du C ou Integer.MAX_VALUE de Java?
TALlama
48
4294967295 === Math.pow(2,32) - 1;
CoolAJ86
13
Alors, quel est le plus petit et le plus grand entier que nous pouvons utiliser pour assurer une précision exacte?
Pacerier
38
Peut-être intéressant de noter qu'il n'y a pas de réel (int) en javascript. Chaque instance de Number est (float) ou NaN.
Beetroot-Beetroot
53
9007199254740992 n'est pas vraiment la valeur maximale, le dernier bit ici est déjà supposé être nul et vous avez donc perdu 1 bit de précision. Le vrai numéro de sécurité est le 9007199254740991 (Number.MAX_SAFE_INTEGER)
Willem D'Haeseleer
461

> = ES6:

Number.MIN_SAFE_INTEGER;
Number.MAX_SAFE_INTEGER;

<= ES5

De la référence :

Number.MAX_VALUE;
Number.MIN_VALUE;

Peter Bailey
la source
23
J'ai modifié la question pour être un peu plus précis sur le fait de vouloir les valeurs entières maximales, pas seulement la valeur numérique maximale. Désolé pour la confusion, ici.
TALlama
5
Le résultat renvoyé est-il garanti égal sur tous les navigateurs?
Pacerier
7
Notez que Number.MIN_VALUEc'est le plus petit nombre positif possible . La moindre valeur (c'est-à-dire moins que toute autre chose) l'est probablement -Number.MAX_VALUE.
Michael Scheper
34
ES6 présente Number.MIN_SAFE_INTEGERetNumber.MAX_SAFE_INTEGER
superlukas
2
Donc, dans ce cas, devrions-nous voter contre la réponse parce qu'elle est incorrecte pour la question mise à jour, ou la laisser parce que le Peter Baily avait raison au moment où il a été répondu?
rocketsarefast
112

Il s'agit de 2 53 == 9 007 199 254 740 992. En effet, les Numbers sont stockés en virgule flottante dans une mantisse de 52 bits.

La valeur min est -2 53 .

Cela fait que des choses amusantes se produisent

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
}

Pour en savoir plus: http://blog.vjeux.com/2010/javascript/javascript-max_int-number-limits.html

Vjeux
la source
1
bien que l'on n'atteigne jamais la fin de cette boucle pour une boucle dans un délai raisonnable, vous pouvez direi += 1000000000
ninjagecko
2
@ninjagecko, il commence à MAX_INT donc la fin est là. En utilisant également i + = 1000000000, cela ne serait plus une boucle infinie. Essayez-le.
Ted Bigham
@TedBigham: Ah oups, j'étais prêt trop vite à travers ça. Merci de m'avoir corrigé deux fois.
ninjagecko
Voir l'argument de Jimmy pour 9 007 199 254 740 991 au lieu de 9 007 199 254 740 992 ici . Cela, combiné à mon suivi, semble convaincant.
TJ Crowder
60

En JavaScript, il existe un numéro 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.

BananaNeil
la source
25
Quelque chose me dit que l'infini ne peut pas être considéré comme un entier. :)
devios1
7
Mais c'est suffisant pour initialiser une minvariable lorsque vous recherchez une valeur minimale.
djjeck
9
Notez queInfinity - 1 === Infinity
H.Wolper
2
aussi (Infinity <100) => false et Math.pow (2,1024) === Infinity
Sijav
6
Ne vaut rien non plus qu'il gère également l'infini négatif. Donc1 - Infinity === -Infinity
dmccabe
41

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

console.log(9007199254740993);

Cependant, il n'y a pas de réponse qui trouve / prouve cela par programme (autre que celle à laquelle CoolAJ86 a fait allusion dans sa réponse qui se terminerait dans 28,56 ans;), voici donc une façon légèrement plus efficace de le faire (pour être précis, c'est plus efficace par environ 28,559999999968312 ans :), avec un violon de test :

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

Briguy37
la source
8
@ CoolAJ86: Lol, j'ai hâte au 15 mars 2040. Si nos chiffres correspondent, nous devrions
organiser
var x = Math.pow (2,53) -3; tandis que (x! = x + 1) x ++; -> 9007199254740991
MickLH
@MickLH: je reçois 9007199254740992 avec ce code . Quel moteur JavaScript utilisez-vous pour tester?
Briguy37
Vous obtenez 9007199254740992 avec votre propre code, je n'ai pas utilisé la valeur finale de x, mais l'évaluation finale de x ++ pour des raisons paranoïaques. Google Chrome btw.
MickLH
@MickLH: l'évaluation x++vous donne la valeur de x avant que l'incrément ne se produise, ce qui explique probablement l'écart. Si vous souhaitez que l'expression ait la même valeur que la valeur finale de x, vous devez la remplacer par ++x.
peterflynn
32

Pour être sûr

var MAX_INT = 4294967295;

Raisonnement

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

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

Si vous ne pouvez pas attendre aussi 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
  • Vous devez vous en tenir à 4294967295ce qui permet Math.pow(2,32) - 1d'éviter les problèmes attendus avec le décalage de bits

Constatation 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);
}());
CoolAJ86
la source
4
ne pouvez-vous pas le démarrer à 2 ^ 53-2 pour tester? (oui vous pouvez, je viens de l'essayer, même avec -3 pour être sûr: var x = Math.pow (2,53) -3; while (x! = x + 1) x ++;) -> 9007199254740991
MickLH
Bonne réponse! De plus, je sais que la valeur est réglée, mais pourquoi ne pas utiliser la recherche binaire pour sa découverte?
higuaro
1
Quel est le plaisir là-dedans? En outre, @ Briguy37 m'a battu: stackoverflow.com/a/11639621/151312
CoolAJ86
notez que ce MAX_INT «sûr» basé sur 32 bits ne fonctionnera pas lors de la comparaison avec des valeurs de date. 4294967295 est donc hier!
Jerry
1
La réponse "Pour être sûr: var MAX_INT = 4294967295;" n'est pas drôle. Si vous ne modifiez pas les bits, ne vous en faites pas (sauf si vous avez besoin d'un entier supérieur à 4294967295, auquel cas vous devriez probablement le stocker sous forme de chaîne et utiliser une bibliothèque bigint).
CoolAJ86
29

La réponse courte est «cela 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 se trouve que les opérateurs au niveau du bit et la longueur maximale d'un tableau sont limités à des entiers 32 bits.)

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

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

Ces limitations sont imposées par la représentation interne de 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, la magnitude de la limite négative est la même que la magnitude de la limite positive, en raison des caractéristiques de la représentation interne, qui comprend en fait un 0 négatif !)

danorton
la source
C'est la réponse sur laquelle je voulais tomber sur la façon de convertir X en un entier 32 bits ou un entier non signé. A voté pour votre réponse.
Charlie Affumigato
29

ECMAScript 6:

Number.MAX_SAFE_INTEGER = Math.pow(2, 53)-1;
Number.MIN_SAFE_INTEGER = -Number.MAX_SAFE_INTEGER;
WaiKit Kung
la source
1
Attention ce n'est pas (encore) supporté par tous les navigateurs! Aujourd'hui, iOS (même pas Chrome), Safari et IE n'aiment pas ça.
cregox
5
Veuillez lire attentivement la réponse, nous n'utilisons pas l'implémentation par défaut de Number.MAX_SAFE_INTEGER dans ECMAScript 6, nous la définissons par Math.pow (2, 53) -1
WaiKit Kung
Je pensais que c'était juste une référence à la façon dont il est implémenté dans ECMA 6! : PI pense que mon commentaire est toujours valable, cependant. Tout est une question de contexte. ;)
cregox
3
Est-il fiable de calculer MAX_SAFE_INTEGERdans tous les navigateurs en travaillant à l'envers? Devriez-vous plutôt avancer? C'est-à-dire, Number.MAX_SAFE_INTEGER = 2 * (Math.pow (2, 52) - 1) + 1;
kjv
Est-ce Math.pow(2, 53)-1une opération sûre? Il va un plus grand que le plus grand entier sûr.
ioquatix
21

De nombreuses réponses d'époques antérieures ont montré le résultat truede 9007199254740992 === 9007199254740992 + 1vérifier que 9 007 199 254 740 991 est l'entier maximum et sûr.

Et si nous continuons à faire de l'accumulation:

input: 9007199254740992 + 1  output: 9007199254740992  // expected: 9007199254740993
input: 9007199254740992 + 2  output: 9007199254740994  // expected: 9007199254740994
input: 9007199254740992 + 3  output: 9007199254740996  // expected: 9007199254740995
input: 9007199254740992 + 4  output: 9007199254740996  // expected: 9007199254740996

Nous avons pu découvrir que parmi les nombres supérieurs à 9 007 199 254 740 992 , seuls les nombres pairs sont représentables .

C'est une entrée pour expliquer comment fonctionne le format binaire 64 bits double précision . Voyons comment 9 007 199 254 740 992 peuvent être conservés (représentés) en utilisant ce format binaire.

Utiliser une version brève pour le démontrer à partir de 4 503 599 627 370 496 :

  1 . 0000 ---- 0000  *  2^52            =>  1  0000 ---- 0000.  
     |-- 52 bits --|    |exponent part|        |-- 52 bits --|

Sur le côté gauche de la flèche, nous avons la valeur de bit 1 , et un point de radix adjacent , puis en multipliant 2^52, nous déplaçons à droite le point de radix de 52 pas, et il va jusqu'à la fin. Nous obtenons maintenant 4503599627370496 en binaire.

Maintenant, nous commençons à accumuler 1 à cette valeur jusqu'à ce que tous les bits soient mis à 1, ce qui équivaut à 9 007 199 254 740 991 en décimal.

  1 . 0000 ---- 0000  *  2^52  =>  1  0000 ---- 0000.  
                       (+1)
  1 . 0000 ---- 0001  *  2^52  =>  1  0000 ---- 0001.  
                       (+1)
  1 . 0000 ---- 0010  *  2^52  =>  1  0000 ---- 0010.  
                       (+1)
                        . 
                        .
                        .
  1 . 1111 ---- 1111  *  2^52  =>  1  1111 ---- 1111. 

Maintenant, parce que dans le format binaire 64 bits à double précision , il alloue strictement 52 bits pour la fraction, il n'y a plus de bit à transporter pour ajouter un 1 de plus, donc ce que nous pouvons faire est de remettre tous les bits à 0, et manipuler la partie exposant:

  |--> This bit is implicit and persistent.
  |        
  1 . 1111 ---- 1111  *  2^52      =>  1  1111 ---- 1111. 
     |-- 52 bits --|                     |-- 52 bits --|

                          (+1)
                                     (radix point has no way to go)
  1 . 0000 ---- 0000  *  2^52 * 2  =>  1  0000 ---- 0000. * 2  
     |-- 52 bits --|                     |-- 52 bits --|

  =>  1 . 0000 ---- 0000  *  2^53 
         |-- 52 bits --| 

Maintenant, nous obtenons le 9 007 199 254 740 992 , et avec un nombre supérieur à celui-ci, ce que le format pourrait contenir est 2 fois la fraction , cela signifie maintenant que chaque 1 ajout sur la partie de la fraction est en fait égal à 2 addition, c'est pourquoi le double -le format binaire de précision 64 bits ne peut pas contenir de nombres impairs lorsque le nombre est supérieur à 9 007 199 254 740 992 :

                            (consume 2^52 to move radix point to the end)
  1 . 0000 ---- 0001  *  2^53  =>  1  0000 ---- 0001.  *  2
     |-- 52 bits --|                 |-- 52 bits --|

Ainsi, lorsque le nombre atteint plus de 9 007 199 254 740 992 * 2 = 18 014 398 509 481 984, seulement 4 fois la fraction pourrait être tenue:

input: 18014398509481984 + 1  output: 18014398509481984  // expected: 18014398509481985
input: 18014398509481984 + 2  output: 18014398509481984  // expected: 18014398509481986
input: 18014398509481984 + 3  output: 18014398509481984  // expected: 18014398509481987
input: 18014398509481984 + 4  output: 18014398509481988  // expected: 18014398509481988

Que diriez-vous du nombre entre [ 2 251 799 813 685 248 , 4 503 599 627 370 496 )?

 1 . 0000 ---- 0001  *  2^51  =>  1 0000 ---- 000.1
     |-- 52 bits --|                |-- 52 bits  --|

La valeur de bit 1 après le point de radix est exactement 2 ^ -1. (= 1/2, = 0,5) Ainsi, lorsque le nombre est inférieur à 4 503 599 627 370 496 (2 ^ 52), il y a un bit disponible pour représenter les 1/2 fois l'entier :

input: 4503599627370495.5   output: 4503599627370495.5  
input: 4503599627370495.75  output: 4503599627370495.5  

Moins de 2 251 799 813 685 248 (2 ^ 51)

input: 2251799813685246.75   output: 2251799813685246.8  // expected: 2251799813685246.75 
input: 2251799813685246.25   output: 2251799813685246.2  // expected: 2251799813685246.25 
input: 2251799813685246.5    output: 2251799813685246.5

// If the digits exceed 17, JavaScript round it to print it.
//, but the value is held correctly:

input: 2251799813685246.25.toString(2) 
output: "111111111111111111111111111111111111111111111111110.01"
input: 2251799813685246.75.toString(2) 
output: "111111111111111111111111111111111111111111111111110.11"
input: 2251799813685246.78.toString(2)   
output: "111111111111111111111111111111111111111111111111110.11"

Et quelle est la gamme disponible de partie exposant ? le format lui attribue 11 bits. Format complet de Wiki : (Pour plus de détails, veuillez y aller)

Format à virgule flottante double IEEE 754.svg

entrez la description de l'image ici

Donc, pour que la partie exposant soit 2 ^ 52, nous devons exactement définir e = 1075.

Carr
la source
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 la 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 testera des puissances de 2 pour trouver lequel, lorsqu'il est "ajouté" 1, est égal à lui-même.

Philippe97
la source
Cela pourrait planter votre application, pensait-il.
Sapphire_Brick
8

Tout ce que vous souhaitez 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 et 0x80000000 est égal à -2147483648.

Scato
la source
6

Essayer:

maxInt = -1 >>> 1

Dans Firefox 3.6, c'est 2 ^ 31 - 1.

Martin Naatz
la source
2
@danorton: Je ne suis pas sûr que vous compreniez ce que vous faites. ^des moyens élevés au pouvoir . Dans la console javascript, ^est XOR , pas augmenté à
kumarharsh
2
ouvrez la console Chrome / Firefox. Tapez 5 ^ 2. En binaire, 5 est 101et 2 est 010. Maintenant, si vous les XOR au niveau du bit, vous obtiendrez 5(101) ^ 2(010) = 7(111) LIRE CECI SI VOUS ÊTES CONFUS Ce qui est discuté ici n'est Math.pow()pas l' ^opérateur
kumarharsh
3
Encore une fois, je ne suis pas du tout confus. J'ai commenté et voté contre ce qui est écrit . Si Math.pow () est ce que l'on veut dire, alors c'est ce qui devrait être écrit. Dans une réponse à une question sur JavaScript, il est inapproprié d'utiliser la syntaxe d'un autre langage. Il est encore plus inapproprié d'utiliser une syntaxe valide en JavaScript, mais avec une interprétation en JavaScript qui a une signification différente de celle prévue.
danorton
10
2 ^ 31 est la façon dont on écrit deux à la trente et unième puissance en anglais. Ce n'est pas dans un bloc de code. Souhaitez-vous vous plaindre que quelqu'un utilise un; dans une réponse, parce que c'est un caractère avec une signification différente en Javascript?
lmm
3
Même si l'on doit écrire 2³¹ et non 2 ^ 31 en texte brut, il est courant de le faire, car la plupart des dispositions de clavier n'ont pas ces caractères par défaut. Au moins, je n'ai eu aucun problème à comprendre ce que signifiait cette réponse.
Jocke
6

Au moment de l' écriture, JavaScript reçoit un nouveau type de données: BigInt. Il s'agit d'une proposition TC39 à l' étape 4 à inclure dans EcmaScript 2020 . BigIntest disponible dans Chrome 67+, FireFox 68+, Opera 54 et Node 10.4.0. Il est en cours dans Safari, et al ... Il introduit des littéraux numériques ayant un suffixe "n" et permet une précision arbitraire:

var a = 123456789012345678901012345678901n;

La précision sera toujours perdue, bien sûr, lorsqu'un tel nombre est (peut-être involontairement) contraint à un type de données numérique.

Et, évidemment, il y aura toujours des limitations de précision dues à la mémoire finie, et un coût en termes de temps pour allouer la mémoire nécessaire et effectuer des calculs arithmétiques sur de si grands nombres.

Par exemple, la génération d'un nombre de cent mille chiffres décimaux prendra un certain temps avant son achèvement:

console.log(BigInt("1".padEnd(100000,"0")) + 1n)

... mais ça marche.

trincot
la source
4

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 OS X) est 9e15. Voici le code que j'ai utilisé pour les tests:

javascript: alert(9e15-(9e15+1));
Raynet
la source
1
Notez que 9e15 = 2 ^ 53 (voir la réponse de @ Jimmy).
Wedge
6
9e15 = 9000000000000000. 2 ^ 53 = 9007199254740992. Par conséquent, pour être pédant, 9e15 est seulement approximativement égal à 2 ^ 53 (avec deux chiffres significatifs).
devios1
@chaiguy Il 9000000000000000y a 1 chiffre significatif. dans «9007199254740992», il y a 15 chiffres significatifs.
Royi Namir
@RoyiNamir Ne voulant pas lancer ici un argument inutile, mais 9000000000000000 a 16 chiffres significatifs. Si vous n'en voulez qu'une seule, elle devra être écrite en 9x10 ^ 15.
devios1
1
@chaiguy No. 9000000000000000tel quel - a 1SF. où 90*10^14a 2. ( sigfigscalculator.appspot.com ) & mathsfirst.massey.ac.nz/Algebra/Decimals/SigFig.htm (section inférieure)
Royi Namir
3

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;
Jérôme
la source
3

Passons aux sources

La description

La MAX_SAFE_INTEGERconstante a une valeur de 9007199254740991(9 007 199 254 740 991 ou ~ 9 quadrillions). Le raisonnement derrière ce nombre est que JavaScript utilise des nombres au format à virgule flottante double précision comme spécifié dans IEEE 754 et ne peut représenter en toute sécurité que les nombres entre -(2^53 - 1)et 2^53 - 1.

Dans ce contexte, la sécurité fait référence à la capacité de représenter exactement des entiers et de les comparer correctement. Par exemple, Number.MAX_SAFE_INTEGER + 1 === Number.MAX_SAFE_INTEGER + 2sera évalué à vrai, ce qui est mathématiquement incorrect. Voir Number.isSafeInteger () pour plus d'informations.

Parce que MAX_SAFE_INTEGER s'agit d'une propriété statique de Number , vous l'utilisez toujours en tant que Number.MAX_SAFE_INTEGER, plutôt qu'en tant que propriété d'un objet Number que vous avez créé.

Compatibilité du navigateur

entrez la description de l'image ici

simhumileco
la source
0

Dans le javascript intégré de Google Chrome, vous pouvez passer à environ 2 ^ 1024 avant que le nombre soit appelé infini.

Tommy
la source
-1

Scato écrit:

tout ce que vous souhaitez 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

Les décimales hexadécimales sont des valeurs positives non signées, donc 0x80000000 = 2147483648 - c'est mathématiquement correct. Si vous voulez en faire une valeur signée, vous devez déplacer vers la droite: 0x80000000 >> 0 = -2147483648. Vous pouvez également écrire 1 << 31.

SammieFox
la source
-7

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

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

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

À moins d'avoir perdu la tête à cette heure de la journée, c'est bien plus grand qu'un entier 64 bits.

jishi
la source
18
ce n'est pas un entier 64 bits, c'est un nombre à virgule flottante 64 bits, dont 52/53 bits sont la partie entière. il peut donc gérer jusqu'à 1e300, mais pas avec une précision exacte.
Jimmy
4
Jimmy a raison. Essayez ceci dans votre navigateur ou en ligne de commande JS:100000000000000010 - 1 => 100000000000000020
Ryan
-7

Node.js et Google Chrome semblent tous deux utiliser des valeurs à virgule flottante 1024 bits, donc:

Number.MAX_VALUE = 1.7976931348623157e+308
TinyTimZamboni
la source
1
-1: le nombre maximal représentable (intégrale non exacte) peut être ~ 2 ^ 1024, mais cela ne signifie pas qu'il s'écarte de la norme IEEE-754 64 bits.
Roy Tinker du
2
MAX_INT? Voulez-vous dire MAX_VALUE?
Raul Guiu
3
c'est le maximum d'une valeur en virgule flottante . Cela ne signifie pas que vous pouvez stocker un int aussi longtemps
phuclv
1
Ou plus précisément, vous ne pouvez pas stocker un int de manière fiable aussi longtemps sans perte de précision . 2^53est appelé MAX_SAFE_INTparce qu'au -dessus de ce point, les valeurs deviennent des approximations, de la même manière que les fractions.
IMSoP