我有一个代码,输入T后跟T行。我想将精度设置为12位小数。如何提高Haskell的精度?
代码:
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
如果输入是:
1
10
然后输出是0.7604599047323508,但我只想要0.760459904732。
答案 0 :(得分:3)
您可以使用Text.Printf中的printf
printf "%.12f" 0.7604599047323508
printf
已重载,因此您需要指定返回类型,但您可以执行以下操作:
showPrec :: Double -> String
showPrec = printf "%.12f"
然后您可以替换show
中使用g
:
g j = showPrec $ sum $ map f[0..j-1]
如果您指定类型,则可以直接在printf
中使用g
:
g :: Double -> String
g j = printf "%.12f" $ sum $ map f[0..j-1]
答案 1 :(得分:0)
主要问题是您是想要更准确的演示还是更准确的数字。
如果您更关心演示文稿,请参阅@ Lee对printf
的回答。
如果您希望(任意)数字比Double
或Float
更准确,请使用科学软件包提供的Scientific
。请注意Integer
类型已具有任意精度。
科学数字可以写成文字,只需要类型注释:
> let d = 3.14159265358979323846264338327950288419716939937510 :: Scientific
> :t d
d :: Scientific
> 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"
> fromFloatDigits 3.1415
3.1415
> read "1e1000000000" :: Scientific
1.0e1000000000
您只需要将某个号码的类型指定为Scientific
。在此之后,您可以像往常一样编写文字并使用Numeric,Floating和RealFrac函数。注意如果表示具有无限小数,则/
可能会发散。 See the documentation for more details.
> d / 2
1.57079632679489661923132169163975144209858469968755
> (d * 1000000000) + 1 == 1000000000 * (d + 1/1000000000)
True