Fermer

septembre 15, 2021

Limitations du type de nombre en JavaScript


Vous ne voulez pas d'erreurs dans vos applications commerciales ou scientifiques, n'est-ce pas ?

En Javascript, le type de nombre est utilisé pour représenter tous les nombres comme les nombres entiers et décimaux (123 ou 123,45). Mais la représentation système sous-jacente de ces nombres a un impact sur la qualité de vos calculs.

Dans ce blog, nous verrons pourquoi les nombres JavaScript ne sont pas nécessairement adaptés aux applications commerciales et scientifiques.

Dans un blog de suivi, nous verrons une solution utilisant la prise en charge des décimales.

Informations générales sur les nombres en JavaScript

Selon la norme ECMAScript, il n'y a qu'un seul type de nombre en JavaScript : la valeur IEEE 754 au format binaire 64 bits double précision.[19659003] Les 64 bits s'utilisent ainsi : 1 bit pour le signe, 11 bits pour l'exposant et 53 bits pour les chiffres significatifs. À partir d'ECMAScript 2015, on peut vérifier si un nombre est dans la plage de nombres à virgule flottante double précision en utilisant Number.isSafeInteger() ainsi que Number.MAX_SAFE_INTEGER et Number.MIN_SAFE_INTEGER .

Au-delà de cette plage, les entiers en JavaScript ne sont plus sûrs et seront une approximation à virgule flottante double précision de la valeur. Nous en verrons ci-dessous quelques exemples.

Référence : https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Number_typ

Limites spécifiques[19659006]Comme tous les nombres en JavaScript sont implémentés avec des nombres à virgule flottante, nous avons les problèmes suivants qui pourraient être préjudiciables aux applications commerciales ou scientifiques :

  • Résultats incorrects avec des nombres inexacts
  • Les calculs flottants ne sont pas déterministes
  • Très grand ou les très petits nombres ne peuvent pas être traités, en particulier lors de l'utilisation d'entiers.

Dans les sections suivantes, nous entrerons dans des explications détaillées pour chacun de ces problèmes. pas une représentation exacte. Cela conduit à des résultats incorrects et à des résultats qui ne peuvent être comparés avec certitude. Autrement dit, les nombres flottants ne peuvent qu'approcher les nombres décimaux couramment utilisés à de nombreuses fins commerciales.

À ce stade, vous vous demandez peut-être de quoi je parle vraiment. Regardons un exemple simple :

Eh bien, en JavaScript, 0,1 + 0,2 est NON égal à 0,3.

Essayez ceci dans une console de navigateur : (pour ouvrir la console par exemple avec Google Chrome , tapez CRTL Shift J sur Windows/Linux ou Command+Option+J sur Mac—voir ici ).

console : console.log(0.1)

Sortie : 0.1

console : console.log(0.2)

Sortie : 0.2

console : console.log(0.1+0.2)[19659003]Sortie : 0.300000000000000004

La raison en est que 0,1 a la représentation suivante sous la forme d'un double : 0.1000000000000000055511151231257827021181583404541015625

Vous pouvez donc imaginer comment répéter ce type d'erreurs de précision sur de nombreuses transactions pourrait entraîner des résultats financiers inacceptables (millions de dollars un an de différences sur certaines transactions).

Note : Seuls les nombres dyadiques ont une représentation exacte. Vous pouvez vérifier ici et aussi ici pour plus d'informations.

Voici un outil pour vérifier si un nombre a une représentation inexacte en tant que flottant.[19659005]Les calculs flottants ne sont pas déterministes

Les calculs flottants ne sont pas déterministes (ils produisent des résultats différents) selon l'architecture de la machine, les versions du compilateur, etc. (lisez ceci pour les problèmes rencontrés par les programmeurs de jeux).

Cela pourrait potentiellement conduire à des résultats différents lorsqu'il est exécuté côté client où les appareils, du téléphone portable aux tablettes en passant par le bureau, exécutent différents systèmes d'exploitation, processeurs matériels et accélérateurs à virgule flottante.

Je n'ai pas personnellement rencontré cela et je serais curieux de le savoir. savoir si vous avez. Veuillez laisser une note dans la section commentaires si vous rencontrez ce problème.

Les très grands nombres ne peuvent pas être traités

Dans le cas des entiers, nous sommes limités tant du côté positif que négatif. JavaScript définit des constantes pour les limites : Number.MAX_SAFE_INTEGER et Number.MIN_SAFE_INTEGER.

console.log(Number.MAX_SAFE_INTEGER) produit 9007199254740991

console.log(Number.MIN_SAFE_INTEGER) produit 9007199254740991

Voici un exemple d'erreurs dans lesquelles vous pourriez tomber :

Number.MAX_SAFE_INTEGER + 1: 9007199254740992 → correct.

Number.MAX_SAFE_INTEGER + 2: 9007199254740992 → clairement incorrect.

En faisant toute opération sur vos numéros, vous pouvez utiliser Number.isSafeInteger() pour vérifier que vous n'avez pas dépassé la plage.

Conclusion

En conclusion, lorsqu'il s'agit d'applications commerciales ou scientifiques, les développeurs JavaScript besoin d'examiner attentivement les limites du type de nombre intégré.

Dans un blog de suivi, nous verrons comment utiliser une bibliothèque décimale pour minimiser les problèmes décrits ici.




Source link