Pourquoi l'ajout de deux décimales dans Javascript produit-il un mauvais résultat?

Duplication possible:
Les mathématiques de JavaScript sont-elles cassées?

Pourquoi JS vante-t-il ces mathématiques simples?

document.write(.1 + .2) // 0.3000000000000004 document.write(.3 + .6) // 0.8999999999999999 

Le premier exemple est supérieur au résultat correct, tandis que le second est moins élevé. ??? !! Comment réparez-vous ceci? Est-ce que vous devez toujours convertir les décimales en entiers avant d'effectuer des opérations? Dois-je seulement m'inquiéter d'ajouter (* et / ne semblent pas avoir le même problème dans mes tests)?

J'ai cherché beaucoup de réponses. Certains tutoriels (comme les formulaires de panier d'achat) prétendent que le problème n'existe pas et ajoutez des valeurs ensemble. Les gurus fournissent des routines complexes pour diverses fonctions mathématiques ou mentionnent JS "fait un travail médiocre" en passant, mais je n'ai pas encore vu d'explication.

Ce n'est pas un problème de JS, mais un ordinateur plus général. Le nombre flottant ne peut pas stocker correctement tous les nombres décimaux, car ils stockent des éléments binaires. Par exemple:

 0.5 is store as b0.1 but 0.1 = 1/10 so it's 1/16 + (1/10-1/16) = 1/16 + 0.0375 0.0375 = 1/32 + (0.0375-1/32) = 1/32 + 00625 ... etc so in binary 0.1 is 0.00011... 

Mais c'est sans fin. Sauf que l'ordinateur doit s'arrêter à un moment donné. Donc, si dans notre exemple, nous nous arrêtons à 0,00011, nous avons 0,09375 au lieu de 0,1.

Quoi qu'il en soit, il ne dépend pas de la langue mais de l'ordinateur. Ce qui dépend de la langue, c'est la façon dont vous affichez les chiffres. Habituellement, la langue ronde les nombres à une représentation acceptable. Apparemment, JS ne l'est pas.

Donc, ce que vous devez faire (le nombre en mémoire est suffisamment précis) est juste pour dire à JS de redonner le nombre "joliment" lors de la conversion en texte.

Vous pouvez essayer la fonction sprintf qui vous donne un bon contrôle de l'affichage d'un nombre.

Il ne s'agit pas d'une limitation javascript, elle s'applique à tous les calculs à virgule flottante. Le problème est que 0,1 et 0,2 et 0,3 ne sont pas représentables exactement comme des flotteurs javascript (ou C ou Java, etc.). Ainsi, la sortie que vous voyez est due à cette inexactitude.

En particulier, seulement certaines sommes de pouvoirs de deux sont exactement représentables. 0.5 = = 0.1b = 2 ^ (- 1), 0.25 = 0.01b = (2 ^ -2), 0.75 = 0.11b = (2 ^ -1 + 2 ^ -2) sont tous OK. Mais 1/10 = 0,000110001100011..b ne peut être exprimé que comme une somme infinie de puissances de 2, que la langue chops à un moment donné. C'est ce hachage qui cause ces légères erreurs.

Ceci est normal pour toutes les langages de programmation car toutes les valeurs décimales ne peuvent être représentées exactement en binaire. Voir ce que chaque scientifique informatique devrait savoir sur l'arithmétique à point flottant

Du guide flottant :

Pourquoi mes nombres, comme 0.1 + 0.2, ne correspondent-ils à un bon cycle 0.3, et à la place, j'ai un résultat étrange comme 0.30000000000000004?

Parce qu'en interne, les ordinateurs utilisent un format (virgule flottante en binaire) qui ne représente pas exactement un nombre comme 0,1, 0,2 ou 0,3.

Lorsque le code est compilé ou interprété, votre "0.1" est déjà arrondis au numéro le plus proche dans ce format, ce qui entraîne une petite erreur d'arrondi avant même que le calcul ne se produise.

Le site a des explications détaillées ainsi que des informations sur la façon de résoudre le problème (et comment décider s'il y a un problème dans votre cas).

Il s'agit de la façon dont les ordinateurs utilisent des nombres flottants. Vous pouvez en lire plus ici: http://docs.sun.com/source/806-3568/ncg_goldberg.html