7
votes

Double laids - Pourquoi 2.9000000000000004 au lieu de 2.9?

Quand je fais 5,2 - 2,3 dans GHCI, je vais obtenir le 2.9000000000000004 au lieu de 2.9. Des résultats aussi laids (et pour un mal humain) apparaissent sur d'autres endroits où travailler avec double ou float.

Pourquoi cela se produit-il? (Ceci est juste pour la curiosité, pas ma vraie question) p>

Ma vraie question: Comment puis-je dire à GHCI de ne pas le faire et montrer les résultats des opérations sur les doubles, tout comme tout autre langage de programmation (et tout autre calculatrice) et tout autant tous les 15 ans les écrirait? P>

Ceci est juste si ennuyeux lorsque j'utilise GHCI comme une belle calculatrice et travaillez sur des listes sur lesquelles j'effectue de telles opérations. P>

map ((-)2.3) [4.0, 3.8, 5.2, 6.4, 1.3, 8.3, 13.7, 9.0, 7.5, 2.4]
[-1.7000000000000002,-1.5,-2.9000000000000004,-4.1000000000000005,0.9999999999999998,-6.000000000000001,-11.399999999999999,-6.7,-5.2,-0.10000000000000009]


1 commentaires

Juste comme un commentaire latéral, c'est probablement la question la plus couramment posée dans l'histoire de tous les temps.


4 Réponses :


18
votes

Pourquoi cela se produit-il?

Parce que certains chiffres de points flottants ne peuvent pas être représentés par un nombre fini de bits sans arrondissement. Numéros de point flottant a un nombre limité de chiffres, ils ne peuvent pas représenter tous les numéros réels avec précision: lorsqu'il y a plus de chiffres que le format le permet, les restes sont omis - le nombre est arrondi.

Vous devriez probablement lire Ce que chaque scientifique doit savoir sur Arithmétique à point flottant et cette réponse .


1 commentaires

En effet, ils ne peuvent même pas représenter tous les rationnels que nous voyons ici



8
votes

Comment puis-je dire GHCI de ne pas le faire et montrer les résultats des opérations sur des doubles, tout comme tout autre langage de programmation (et calculatrice) et tout comme tous les 15 ans les écrirait?

Étant donné que ces résultats sont les résultats réels GHCI (et votre calculatrice standard * ), vous ne pouvez pas modifier la représentation interne du résultat ( Voir la réponse de TNI ). Puisque vous souhaitez afficher uniquement un nombre fixe de décimales, il s'agit davantage de la présentation (comparer à printf ("% F.2", ...) in c ).

Une solution à cela peut être trouvé dans https://stackoverflow.com/a/2327801/1139697 . Il peut être appliqué comme ceci: xxx

Notez que cela ne sera pas réalisable si vous souhaitez continuer le calcul. Si vous voulez exact arithmétique, vous préférez en utilisant rationnel de toute façon. N'oubliez pas que votre contribution devrait être rationnelle ASWELL dans ce cas.

* Oui, même votre calculatrice standard fait la même chose, la seule raison pour laquelle vous ne voyez pas la présentation fixe est la présentation fixe , il ne peut pas montrer plus qu'un nombre fixe de décimales.


1 commentaires

En fait, beaucoup de calculatrices de poche plus simples utilisent BCD , qui ne souffre pas de cette problème mais est totalement inapproprié pour faire quelque chose de plus avancé que les racines carrées de manière efficace. Vous pourriez dire qu'il contourne le bug de la façon de compter de l'homme ...



3
votes

C'est la nature des nombres de points flottants qu'ils ne peuvent pas représenter exactement de chiffres réels (ni rationnels). Haskell Conversion par défaut sur String garantit que lorsque le numéro est lu dans vous, obtenez exactement la même représentation. Si vous voulez une manière différente d'imprimer des numéros, vous pouvez créer votre propre type qui montre des chiffres différemment.

quelque chose comme (non testé): xxx

ceci crée une copie du Double TYPE, mais avec une autre exemple d'instance imprime quelques décimales. La déclaration par défaut rend le compilateur choisi ce type lorsqu'il y a une ambiguïté. Oh, et pour faire ce travail, vous avez besoin de quelques extensions de langue.

Vous pouvez également essayer le type Creal à partir des numéros Numéros .


0 commentaires

3
votes

Comment puis-je dire à GHCI de ne pas le faire et montrer les résultats des opérations sur des doubles comme tout autre langage de programmation (et calculatrice) serait

Avez-vous réellement essayé de "tout autre langage de programmation"? Ou êtes-vous simplement intimidant?

FWIW, voici la sortie d'un interprète pour une langue qui utilise le JVM: xxx

me semble que Si vous obtenez le même résultat avec toutes les langues JVM. Et puisque la JVM est écrite en C ++, des chances sont que le résultat est le même. Et étant donné que la plupart des langues sont écrites en C / C ++, il est probable que vous obteniez que vous obtenez aussi le même résultat même avec ces langues. Sauf si elles sont si "conviviales" et effectuer des arrondis que vous n'avez pas demandé.


0 commentaires