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
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
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.
est-il une version qui gère les nombres négatifs correctement? – Martijn
Si vous voulez gérer des nombres négatifs, utilisez "readSigned readFloat". – Martijn