2012-11-26 4 views
5

Pour lire un entier écrit sous forme décimale est assez simple:Comment lire un entier écrit en forme exponentielle avec Haskell?

Prelude> read "1000000000" :: Int 
1000000000 

Mais comment lire un entier écrit sous forme exponetial?

Prelude> read "10e+9" :: Int 
*** Exception: Prelude.read: no parse 

Y at-il une fonction dans le Prelude de le faire, ou avons-nous besoin pour analyser l'expression?

Merci pour toute réponse.

+2

Rien dans le 'Prelude', j'ai peur d'écrire votre propre analyseur. –

+0

Votre exemple fonctionne pour moi (bien qu'il déborde) en utilisant ghc 7.0.4. – dave4420

+3

@ dave4420 Ne fonctionne plus avec ghc> = 7.4. D'après le rapport, cela n'aurait pas dû fonctionner avant. –

Répondre

2

Selon le format exact de la chaîne, vous pouvez simplement read dans un type à virgule flottante:

> read "10e+9" :: Double 
1.0e10 

then convert to an integral type - Je vous recommande Integer au lieu de Int:

> floor (read "10e+9" :: Double) :: Integer 
10000000000 
+0

'Prélude> étage 10e78 ==> 9999999999999999673560075006595519222746403606649979913266024618633003221909504' –

+0

@Will' ghci> 10e780', 'ghci> étage 10e780' dois aimer les nombres flottants. –

+0

Il échoue à la lecture "5.e-003", que certains logiciels d'ingénierie produisent. – CMCDragonkai

3

Voici un parseur

readI xs = let (m,e) = break (=='e') xs in 
    read m * 10^case e of 
     "" -> 1 
     ('e':'+':p) -> read p 
     ('e':p) -> read p 

Donner

Main> readI "3e5" 
300000 
Main> readI "3e+500" 
300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 
Main> readI "3e+500" :: Int 
0 
Main> readI "3e+500" :: Integer 
300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 

Et aussi

Main> readI "32e-5" 
Program error: Prelude.^: negative exponent 

Nous pourrions essayer de faire face à des exposants négatifs qui donnent des réponses entières mais seraient trop puissantes pour une fonction de lecture.

Questions connexes