2012-11-26 31 views
5

Để đọc một số nguyên được viết dưới dạng số thập phân là khá đơn giản:Làm thế nào để đọc một số nguyên được viết theo dạng mũ với Haskell?

Prelude> read "1000000000" :: Int 
1000000000 

Nhưng làm thế nào để đọc một số nguyên viết bằng hình thức exponetial?

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

Có chức năng nào trong số Prelude để thực hiện điều đó hay chúng tôi cần phân tích cú pháp biểu thức?

Cảm ơn bạn đã trả lời.

+2

Không có gì trong 'Prelude', bạn cần phải viết trình phân tích cú pháp của riêng mình, tôi sợ. –

+0

Ví dụ của bạn làm việc cho tôi (mặc dù nó tràn) bằng cách sử dụng ghc 7.0.4. – dave4420

+3

@ dave4420 Không hoạt động với ghc> = 7.4 nữa. Nó không nên làm việc trước đó một trong hai, theo báo cáo, iirc. –

Trả lời

2

Tùy thuộc vào định dạng chính xác của chuỗi, bạn có thể chỉ read nó thành một loại dấu chấm động:

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

then convert to an integral type - tôi khuyên bạn nên Integer thay vì Int:

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

'Prelude> floor 10e78 ==> 9999999999999999673560075006595519222746403606649979913266024618633003221909504' –

+0

@Will' ghci> 10e780', 'ghci> tầng 10e780' phải yêu số dấu phẩy động. –

+0

Nó không thành công khi đọc "5.e-003", mà một số phần mềm kỹ thuật sản xuất. – CMCDragonkai

3

Dưới đây là trình phân tích cú pháp

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 

Và cũng

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

Chúng ta có thể cố gắng để làm cho nó đối phó với số mũ âm mà cho nguyên câu trả lời nhưng đó sẽ là quá mức cần thiết cho một chức năng đọc.

Các vấn đề liên quan