- class (C a, C a) => C a where
- 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 whereSource

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.

fixSplitFraction :: (C a, C b, Ord a) => (b, a) -> (b, a)Source

fastFraction :: (RealFrac a, C a) => (a -> a) -> a -> aSource

preludeFraction :: (RealFrac a, C a) => a -> aSource

fixFraction :: (C a, Ord a) => a -> aSource

approxRational :: (C a, C a) => a -> a -> RationalSource

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

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

genericTruncate :: (Ord a, C a, C b) => a -> bSource

genericRound :: (Ord a, C a, C b) => a -> bSource

genericFraction :: (Ord a, C a) => a -> aSource

genericSplitFraction :: (Ord a, C a, C b) => a -> (b, a)Source

genericPosFloor :: (Ord a, C a, C b) => a -> bSource

genericPosCeiling :: (Ord a, C a, C b) => a -> bSource

genericPosRound :: (Ord a, C a, C b) => a -> bSource

genericPosFraction :: (Ord a, C a) => a -> aSource

genericPosSplitFraction :: (Ord a, C a, C b) => a -> (b, a)Source