2010-04-01 8 views
3

J'écris une fonction dans laquelle j'ai besoin de lire une chaîne contient un nombre à virgule flottante et le ramener à Rational. Mais quand je fais toRational (read input :: Double), il ne tourne pas pour exemple: 0.9 en 9 % 10 comme prévu, mais 81% ..... 9007 ... Thxproblème avec le nombre double et rationnel

Répondre

10

Ce comportement est correct. Le numéro 0.9 n'est pas représentable comme Double, pas dans Haskell, C ou Java. C'est parce que Double et Float utilisent la base 2: ils ne peuvent représenter qu'un certain sous-ensemble des fractions dyadiques exactement. Pour obtenir le comportement souhaité, importez le module Numeric et utilisez la fonction readFloat. L'interface est assez bancale (elle utilise le type ReadS), vous devrez donc l'envelopper un peu. Voici comment vous pouvez l'utiliser:

import Numeric 
myReadFloat :: String -> Rational -- type signature is necessary here 
myReadFloat str = 
    case readFloat str of 
     ((n, []):_) -> n 
     _ -> error "Invalid number" 

Et le résultat:

> myReadFloat "0.9" 
9 % 10 
+0

est-il une version qui gère les nombres négatifs correctement? – Martijn

+0

Si vous voulez gérer des nombres négatifs, utilisez "readSigned readFloat". – Martijn

1

nombres à virgule flottante binaire ne peuvent pas représenter avec précision tous les numéros que la base -10 peut. Le nombre que vous voyez comme 0.9 n'est pas précisément 0.9 mais quelque chose de très proche. N'utilisez jamais de types à virgule flottante nécessitant une précision décimale - ils ne peuvent tout simplement pas le faire.

Questions connexes