Algebra.RealField
 Contents generic implementation of round functions
Synopsis
class (C a, C a) => C a where
 splitFraction :: C b => a -> (b, a) fraction :: a -> a ceiling :: C b => a -> b floor :: C b => a -> b truncate :: C b => a -> b round :: C b => a -> b
fastSplitFraction :: (RealFrac a, C a, C b) => (a -> Int) -> (Int -> a) -> a -> (b, a)
fixSplitFraction :: (C a, C b, Ord a) => (b, a) -> (b, a)
fastFraction :: (RealFrac a, C a) => (a -> a) -> a -> a
preludeFraction :: (RealFrac a, C a) => a -> a
fixFraction :: (C a, Ord a) => a -> a
splitFractionInt :: (C a, Ord a) => (a -> Int) -> (Int -> a) -> a -> (Int, a)
floorInt :: (C a, Ord a) => (a -> Int) -> (Int -> a) -> a -> Int
ceilingInt :: (C a, Ord a) => (a -> Int) -> (Int -> a) -> a -> Int
roundInt :: (C a, Ord a) => (a -> Int) -> (Int -> a) -> a -> Int
approxRational :: (C a, C a) => a -> a -> Rational
powersOfTwo :: C a => [a]
pairsOfPowersOfTwo :: (C a, C b) => [(a, b)]
genericFloor :: (Ord a, C a, C b) => a -> b
genericCeiling :: (Ord a, C a, C b) => a -> b
genericTruncate :: (Ord a, C a, C b) => a -> b
genericRound :: (Ord a, C a, C b) => a -> b
genericFraction :: (Ord a, C a) => a -> a
genericSplitFraction :: (Ord a, C a, C b) => a -> (b, a)
genericPosFloor :: (Ord a, C a, C b) => a -> b
genericPosCeiling :: (Ord a, C a, C b) => a -> b
genericHalfPosFloorDigits :: (Ord a, C a, C b) => a -> ((a, b), [Bool])
genericPosRound :: (Ord a, C a, C b) => a -> b
genericPosFraction :: (Ord a, C a) => a -> a
genericPosSplitFraction :: (Ord a, C a, C b) => a -> (b, a)
Documentation
 class (C a, C a) => C a where Source

Minimal complete definition: splitFraction or floor

There are probably more laws, but some laws are

``` (fromInteger.fst.splitFraction) a + (snd.splitFraction) a === a
ceiling (toRational x) === ceiling x :: Integer
truncate (toRational x) === truncate x :: Integer
floor (toRational x) === floor x :: Integer
```

If there wouldn't be Real.C a and ToInteger.C b constraints, we could also use this class for splitting ratios of polynomials.

As an aside, let me note the similarities between splitFraction x and x divMod 1 (if that were defined). In particular, it might make sense to unify the rounding modes somehow.

IEEEFloat-specific calls are removed here (cf. Prelude.RealFloat) so probably nobody will actually use this default definition.

Henning: New function fraction doesn't return the integer part of the number. This also removes a type ambiguity if the integer part is not needed.

The new methods fraction and splitFraction differ from Prelude.properFraction semantics. They always round to floor. This means that the fraction is always non-negative and is always smaller than 1. This is more useful in practice and can be generalised to more than real numbers. Since every T denominator type supports divMod, every T can provide fraction and splitFraction, e.g. fractions of polynomials. However the ''integral'' part would not be of type class C.

Can there be a separate class for fraction, splitFraction, floor and ceiling since they do not need reals and their ordering?

Note: All of these methods can be defined exclusively with functions from Ord and Ring. We could write a power-of-two-algorithm like the one for finding the number of digits of an Integer in FixedPoint-fractions module. This would even be reasonably efficient. I think the module should be renamed to RealRing, and the superclass constraint should be lifted from Field to Ring.

We might also add a round method, that rounds 0.5 always up or always down. This is much more efficient in inner loops and is acceptable or even preferable for many applications.

The ToInteger constraint can be lifted to Ring.

Methods
 splitFraction :: C b => a -> (b, a) Source
 fraction :: a -> a Source
 ceiling :: C b => a -> b Source
 floor :: C b => a -> b Source
 truncate :: C b => a -> b Source
 round :: C b => a -> b Source
Instances
 C Double C Float C T C T C a => C (T a) (C a, C a) => C (T a)
 fastSplitFraction :: (RealFrac a, C a, C b) => (a -> Int) -> (Int -> a) -> a -> (b, a) Source
 fixSplitFraction :: (C a, C b, Ord a) => (b, a) -> (b, a) Source
 fastFraction :: (RealFrac a, C a) => (a -> a) -> a -> a Source
 preludeFraction :: (RealFrac a, C a) => a -> a Source
 fixFraction :: (C a, Ord a) => a -> a Source
 splitFractionInt :: (C a, Ord a) => (a -> Int) -> (Int -> a) -> a -> (Int, a) Source
 floorInt :: (C a, Ord a) => (a -> Int) -> (Int -> a) -> a -> Int Source
 ceilingInt :: (C a, Ord a) => (a -> Int) -> (Int -> a) -> a -> Int Source
 roundInt :: (C a, Ord a) => (a -> Int) -> (Int -> a) -> a -> Int Source
 approxRational :: (C a, C a) => a -> a -> Rational Source
TODO: Should be moved to a continued fraction module.
generic implementation of round functions
 powersOfTwo :: C a => [a] Source
 pairsOfPowersOfTwo :: (C a, C b) => [(a, b)] Source
 genericFloor :: (Ord a, C a, C b) => a -> b Source
The generic rounding functions need a number of operations proportional to the number of binary digits of the integer portion. If operations like multiplication with two and comparison need time proportional to the number of binary digits, then the overall rounding requires quadratic time.
 genericCeiling :: (Ord a, C a, C b) => a -> b Source
 genericTruncate :: (Ord a, C a, C b) => a -> b Source
 genericRound :: (Ord a, C a, C b) => a -> b Source
 genericFraction :: (Ord a, C a) => a -> a Source
 genericSplitFraction :: (Ord a, C a, C b) => a -> (b, a) Source
 genericPosFloor :: (Ord a, C a, C b) => a -> b Source
 genericPosCeiling :: (Ord a, C a, C b) => a -> b Source
 genericHalfPosFloorDigits :: (Ord a, C a, C b) => a -> ((a, b), [Bool]) Source
 genericPosRound :: (Ord a, C a, C b) => a -> b Source
 genericPosFraction :: (Ord a, C a) => a -> a Source
 genericPosSplitFraction :: (Ord a, C a, C b) => a -> (b, a) Source