module Numeric.AffineForm.ExplicitRounding (
ExplicitRounding,
eps, prev, next,
(+/), (+\),
(-/), (-\),
(*/), (*\)
) where
import Numeric.Interval as IA
import Data.Ratio
class (Ord a, Num a) => ExplicitRounding a where
eps :: a -> a
prev :: a -> a
next :: a -> a
(+/) :: a -> a -> a
(+\) :: a -> a -> a
(-/) :: a -> a -> a
(-\) :: a -> a -> a
(*/) :: a -> a -> a
(*\) :: a -> a -> a
prev x = x - eps x
next x = x + eps x
x +/ y = next $ x + y
x +\ y = prev $ x + y
x -/ y = next $ x - y
x -\ y = prev $ x - y
x */ y = next $ x * y
x *\ y = prev $ x * y
instance ExplicitRounding Int where
eps = const 0
instance (Integral a, ExplicitRounding a) => ExplicitRounding (Ratio a) where
eps x = (eps $ numerator x) % (abs (denominator x) - (eps $ denominator x))
instance ExplicitRounding Float where
eps 0 = eps $ 2e-36
eps x = encodeFloat 2 (snd $ decodeFloat x)
instance ExplicitRounding Double where
eps 0 = eps $ 1e-300
eps x = encodeFloat 2 (snd $ decodeFloat x)