Eigenvalue
Eigenvalue

Reputation: 1133

Dividing by small quantities in haskell

I have a question regarding numerical operations in Haskell.

I have a basic function:

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

When I test it, this is the output I get:

    *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> 

When the divisor gets smaller, it makes the answer automatically go towards zero, rather than a more refined convergence toward 4. I'm curious as to why this is happening, especially given my type definition.

Upvotes: 1

Views: 96

Answers (2)

chi
chi

Reputation: 116164

In your code the 0.000000000000000001 is probably being defaulted to Double, causing a loss of precision after 2 is added because of rounding.

Using an exact representation such as Rational does not exhibit the same issue:

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

In the last line the loss of precision happens after the incremental ratio is computed, so the result is close to the exact fraction shown above.

Upvotes: 3

zmbq
zmbq

Reputation: 39023

This is probably due to floating point rounding errors. You can use fixed point numbers, as is shown here.

Upvotes: 0

Related Questions