Numéros longs en soustrayant javascript
-
20-09-2019 - |
Question
Pourquoi q == 0 dans le script suivant?
<script>
var start = 1234567890123456789;
var end = 1234567890123456799;
var q = end - start;
alert(q);
</script>
Je pense que le résultat devrait être 10. Quelle est la bonne façon de soustraire ces deux chiffres?
La solution
Parce que nombres en JavaScript sont à virgule flottante. Ils ont une précision limitée.
Lorsque JavaScript voit un très long, il arrondit au nombre le plus proche, il peut représenter un flotteur 64 bits. Dans votre script, start
et end
s'arrondi à la même valeur.
alert(1234567890123456789); // says: 1234567890123456800
alert(1234567890123456799); // says: 1234567890123456800
Il n'y a aucun moyen intégré pour effectuer des opérations arithmétiques précises sur les grands entiers, mais vous pouvez utiliser une bibliothèque BigInteger comme celui-ci .
Autres conseils
Jason déjà posté pourquoi. Pour une solution, vous pouvez obtenir une bibliothèque Javascript BigInt http: // www- cs-students.stanford.edu/~tjw/jsbn/
const subtract = (a, b) => [a, b].map(n => [...n].reverse()).reduce((a, b) => a.reduce((r, d, i) => {
let s = d - (b[i] || 0)
if (s < 0) {
s += 10
a[i + 1]--
}
return '' + s + r
}, '').replace(/^0+/, ''))
Mieux utiliser la bibliothèque grand entier pour ces choses de manière à gérer tous les différents cas de test.
Ceci est juste pour le cas général, vous pouvez utiliser ....
Il est expliqué dans le JavaScript documentation :
Selon la norme ECMAScript, il n'y a qu'un seul type de numéro: la double précision 64- bit format binaire IEEE 754 (valeur numéros entre
-(2
53
-1)
et2
53
-1
). Il n'y a pas de type spécifique pour les entiers.
format double virgule flottante de précision explique:
Entre
2
52
= 4,503,599,627,370,496
et2
53
= 9,007,199,254,740,992
les nombres représentables sont exactement les entiers. Pour la plage suivante, de2
53
à2
54
, tout est multiplié par2
, de sorte que les nombres représentables sont les même ceux, etc.
(Tous les nombres entiers plus petits que 2
52
sont représentés exactement.)
1234567890123456789
et 1234567890123456799
sont plus grandes que 2
60
= 1152921504606846976
. A cette ampleur ne représente qu'environ 1% des nombres entiers sont stockés exactement en utilisant la double précision format en virgule flottante.
Ces deux ne peuvent pas être stockées exactement. Ils ont tous deux sont arrondis à 1234567890123456800
.
Le JavaScript explique également comment dire si un un nombre entier est stocké exactement:
[...] et à partir de ECMAScript 6, vous êtes également en mesure de vérifier si un nombre est le nombre double précision à virgule flottante plage à l'aide
Number.isSafeInteger()
ainsi queNumber.MAX_SAFE_INTEGER
etNumber.MIN_SAFE_INTEGER
. Au-delà de cette gamme, les entiers en JavaScript ne sont pas plus sûrs et un point flottante double précision approximation de la valeur.