Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to read an integer written in exponential form with Haskell?

Tags:

haskell

ghci

To read an integer written in decimal form is quite simple :

Prelude> read "1000000000" :: Int
1000000000

But how to read an integer written in exponetial form ?

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

Is there a function in the Prelude to do that, or do we need to parse the expression?

Thanks for any reply.

like image 372
Fopa Léon Constantin Avatar asked Nov 26 '12 15:11

Fopa Léon Constantin


2 Answers

Here's a parser

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

Giving

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

And also

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

We could try to make it cope with negative exponents that give integer answers but that would be overkill for a read function.

like image 53
AndrewC Avatar answered Sep 28 '22 07:09

AndrewC


Depending on the exact format of the string, you could just read it into a floating point type:

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

then convert to an integral type -- I'd recommend Integer instead of Int:

> floor (read "10e+9" :: Double) :: Integer
10000000000
like image 23
Matt Fenwick Avatar answered Sep 28 '22 07:09

Matt Fenwick