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]
4 Réponses :
Pourquoi cela se produit-il? p> blockQuote>
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. p>
Vous devriez probablement lire Ce que chaque scientifique doit savoir sur Arithmétique à point flottant et cette réponse . P>
En effet, ils ne peuvent même pas représenter tous les rationnels que nous voyons ici
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? P>
Étant donné que ces résultats sont les résultats réels GHCI (et votre calculatrice standard * sup>), 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 em> (comparer à
printf ("% F.2", ...) code> in c ). P>Une solution à cela peut être trouvé dans https://stackoverflow.com/a/2327801/1139697 . Il peut être appliqué comme ceci: p>
xxx pré> Notez que cela ne sera pas réalisable si vous souhaitez continuer le calcul. Si vous voulez exact em> arithmétique, vous préférez en utilisant
rationnel code> de toute façon. N'oubliez pas que votre contribution devrait être rationnelle ASWELL dans ce cas. P>* 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. sup> p> blockquote>
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 ...
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é): p> ceci crée une copie du Vous pouvez également essayer le type Double CODE> TYPE, mais avec une autre exemple code> d'instance imprime quelques décimales. La déclaration code> par défaut code> 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. P> Creal code> à partir des numéros Numéros code>. P > p>
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 p>
Avez-vous réellement essayé de "tout autre langage de programmation"? Ou êtes-vous simplement intimidant? P>
FWIW, voici la sortie d'un interprète pour une langue qui utilise le JVM: p>
xxx pré> 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é. P> BlockQuote>
Juste comme un commentaire latéral, c'est probablement la question la plus couramment posée dans l'histoire de tous les temps.