Ian Stewart
Ian Stewart

Reputation: 465

How to get a decimal string from a Double instead of scientific notation in Haskell?

I need to divide a list of numbers by 100 to be printed, for example:

map (/100) [29, 3, 12]

produces:

[0.29,3.0e-2,0.12]

however I need:

[0.29,0.03,0.12]

How do I do this in Haskell? Any ideas really appreciated.

Upvotes: 12

Views: 3295

Answers (3)

Golden Thumb
Golden Thumb

Reputation: 2537

What works for me is: cabal install numbers and then in GHCi

λ: import Data.Number.CReal
λ: map (/(100 :: CReal)) [29,3,12]
[0.29,0.03,0.12]

Upvotes: 3

Ian Stewart
Ian Stewart

Reputation: 465

Many thanks for all your comments, now I understand the problem I don't mind using workarounds. The code was to find the lengths of sections of music based on the time each section begins - in the form of 1.28 for 1 minute 28 seconds. Now the result is a list with the timings as strings but that is not a problem. For anyone who is interested, here is the function with the workaround:

subtractMinutes :: RealFrac a => [a] -> [[Char]]
subtractMinutes (x:xs) = take (length (xs)) (zz : subtractMinutes xs)
    where ya = (head(xs) - x) * 100
          ys = truncate (head(xs)) - truncate(x)
          yz = ya - (fromIntegral(ys) * 40)
          yx = round(yz)
          za = div yx 60
          zs = mod yx 60
          zz = show(za) ++ "." ++ zx
          zx = if zs < 10 then "0" ++ show(zs) else show(zs)

Upvotes: 0

Zeta
Zeta

Reputation: 105885

0.03 and 3.0e-2 are the same number. Internally, GHC uses showFloat to print it, which will result in the scientific notation whenever the absolute value is outside the range 0.1 and 9,999,999.

Therfore, you have to print the values yourself, for example with printf from Text.Printf or showFFloat from Numeric:

import Numeric

showFullPrecision :: Double -> String
showFullPrecision x = showFFloat Nothing x ""

main = putStrLn (showFullPrecision 0.03)

Depending on your desired output, you need to write some more functions.

Upvotes: 14

Related Questions