user3786422
user3786422

Reputation: 303

Set precision in Haskell

I am having a code that take input T and followed by T lines. I want to set precision to 12 decimal places. How can I increase precision in Haskell?

Code:

f i=(-1)**i/(2*i+1) 
g j=show$sum$map f[0..j-1]
p(_:l)=map(g.read)l
main=interact$unlines.p.lines

Like if input is:

1
10

Then output is 0.7604599047323508, but I want only 0.760459904732.

Upvotes: 4

Views: 1843

Answers (2)

ROGUH
ROGUH

Reputation: 661

The main question is whether you want more accurate presentation or more accurate numbers. See @Lee's answer for printf if you're more concerned about presentation.

Arbitrary Precision

If you want numbers that are (arbitrarily) more accurate than Double or Float, use Scientific offered by the scientific package. Note the Integer type already has arbitrary precision.

Scientific numbers can be written as literals, they only need type annotations:

> let d = 3.14159265358979323846264338327950288419716939937510 :: Scientific
> :t d
d :: Scientific

Scientific -> String

> formatScientific Exponent (Just 3) d
"3.142e0"

> formatScientific Generic (Just 3) d
"3.142"

> formatScientific Generic (Just 100) d
"3.1415926535897932384626433832795028841971693993751000000000000000000000000000000000000000000000000000"

> formatScientific Generic (Just 16) d
"3.1415926535897932"

Float -> Scientific

> fromFloatDigits 3.1415
3.1415

String -> Scientific

> read "1e1000000000" :: Scientific
1.0e1000000000

General use

You only need to specify the type of one of your numbers as Scientific. After this, you can simply write literals and use Numeric, Floating and RealFrac function as usual. Note / might diverge if the representation has infinite decimals. See the documentation for more details.

> d / 2
1.57079632679489661923132169163975144209858469968755

> (d * 1000000000) + 1 == 1000000000 * (d + 1/1000000000)
True

Upvotes: 2

Lee
Lee

Reputation: 144136

You can use printf from Text.Printf

printf "%.12f" 0.7604599047323508

printf is overloaded so you need to specify the return type but you can do:

showPrec :: Double -> String
showPrec = printf "%.12f"

then you can replace the use of show in g:

g j = showPrec $ sum $ map f[0..j-1]

you can use printf directly in g if you specify the type:

g :: Double -> String
g j = printf "%.12f" $ sum $ map f[0..j-1]

Upvotes: 5

Related Questions