在haskell中分成少量

时间:2014-08-31 20:29:40

标签: haskell

我对Haskell中的数值运算有疑问。

我有一个基本功能:

derv::(Num a, Fractional a) => (a -> a) -> a -> a -> a
derv f a deltax = ((f (a+deltax))-(f a))/deltax

当我测试它时,这是我得到的输出:

    *Main> derv (\x->x*x) 2 0.000000000000000001
    0.0
    *Main> derv (\x->x*x) 2 0.00000000000001
    4.085620730620576
    *Main> derv (\x->x*x) 2 0.0000000001
    4.000000330961484
    *Main> derv (\x->x*x) 2 0.0001
    4.0001000000078335
    *Main> 

当除数变小时,它会使答案自动趋向零,而不是向4更精确的收敛。我很好奇为什么会发生这种情况,特别是考虑到我的类型定义。

2 个答案:

答案 0 :(得分:3)

在您的代码中,0.000000000000000001可能是defaultedDouble,导致 由于四舍五入,添加2后精度会下降。

使用Rational之类的精确表示不会出现同样的问题:

> import Data.Ratio
> derv (\x->x*x) 2 0.000000000000000001 :: Rational
4000000000000000001 % 1000000000000000000
> fromRational (derv (\x->x*x) 2 0.000000000000000001) :: Double
4.0

在最后一行中,在计算增量比后发生精度损失,因此结果接近上面显示的精确分数。

答案 1 :(得分:0)

这可能是由于浮点舍入错误造成的。您可以使用固定点编号,如here所示。