Est-ce défini par la langue? Y a-t-il un maximum défini? Est-ce différent dans différents navigateurs?
la source
Est-ce défini par la langue? Y a-t-il un maximum défini? Est-ce différent dans différents navigateurs?
JavaScript a deux types de nombres: Number
et 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_INTEGER
est:
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.
Notez que tous les entiers positifs et négatifs dont la magnitude n'est pas supérieure à 2 53 sont représentables dans le
Number
type (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.
4294967295 === Math.pow(2,32) - 1;
> = ES6:
Number.MIN_SAFE_INTEGER;
Number.MAX_SAFE_INTEGER;
<= ES5
De la référence :
Number.MAX_VALUE;
Number.MIN_VALUE;
Number.MIN_VALUE
c'est le plus petit nombre positif possible . La moindre valeur (c'est-à-dire moins que toute autre chose) l'est probablement -Number.MAX_VALUE
.
Number.MIN_SAFE_INTEGER
etNumber.MAX_SAFE_INTEGER
Il s'agit de 2 53 == 9 007 199 254 740 992. En effet, les Number
s 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
i += 1000000000
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.
min
variable lorsque vous recherchez une valeur minimale.
Infinity - 1 === Infinity
1 - Infinity === -Infinity
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);
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
.
var MAX_INT = 4294967295;
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 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
9007199254740992 === Math.pow(2, 53) + 1
est une preuve suffisante4294967295
ce qui permet Math.pow(2,32) - 1
d'éviter les problèmes attendus avec le décalage de bitsConstatation 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);
}());
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 !)
ECMAScript 6:
Number.MAX_SAFE_INTEGER = Math.pow(2, 53)-1;
Number.MIN_SAFE_INTEGER = -Number.MAX_SAFE_INTEGER;
MAX_SAFE_INTEGER
dans 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;
Math.pow(2, 53)-1
une opération sûre? Il va un plus grand que le plus grand entier sûr.
De nombreuses réponses d'époques antérieures ont montré le résultat true
de 9007199254740992 === 9007199254740992 + 1
vé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)
Donc, pour que la partie exposant soit 2 ^ 52, nous devons exactement définir e = 1075.
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.
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.
Essayer:
maxInt = -1 >>> 1
Dans Firefox 3.6, c'est 2 ^ 31 - 1.
^
des moyens élevés au pouvoir . Dans la console javascript, ^
est XOR , pas augmenté à
101
et 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
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 . BigInt
est 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.
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));
9000000000000000
y a 1 chiffre significatif. dans «9007199254740992», il y a 15 chiffres significatifs.
9000000000000000
tel quel - a 1
SF. où 90*10^14
a 2. ( sigfigscalculator.appspot.com ) & mathsfirst.massey.ac.nz/Algebra/Decimals/SigFig.htm (section inférieure)
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;
La
MAX_SAFE_INTEGER
constante a une valeur de9007199254740991
(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)
et2^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 + 2
sera é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 queNumber.MAX_SAFE_INTEGER
, plutôt qu'en tant que propriété d'un objet Number que vous avez créé.
Dans le javascript intégré de Google Chrome, vous pouvez passer à environ 2 ^ 1024 avant que le nombre soit appelé infini.
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.
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.
100000000000000010 - 1 => 100000000000000020
Node.js et Google Chrome semblent tous deux utiliser des valeurs à virgule flottante 1024 bits, donc:
Number.MAX_VALUE = 1.7976931348623157e+308
2^53
est appelé MAX_SAFE_INT
parce qu'au -dessus de ce point, les valeurs deviennent des approximations, de la même manière que les fractions.
1n << 10000n
est 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).