(Data.Fixed.mod' n d) not less than d
If one encounters the expression mod' n d
, one might reasonably assume that the result of the expression is less than d
. However, this is not true:
$ ghci
>>=mod' 3.154831645792668e16 (2 * pi)
8.0
The definition of mod'
reveals the problem (when a
is an IEEE float):
mod' :: (Real a) => a -> a -> a
mod' n d = n - (fromInteger f) * d where
f = div' n d
Substituting:
mod' 3.154831645792668e16 (2 * pi)
->
3.154831645792668e16 - (fromIntegral 5021070510506425) * (2 * pi)
->
3.154831645792668e16 - 3.1548316457926672e16
->
8.0
We can repair mod' if we're willing to add a Fractional
constraint:
mod' :: (Fractional a, Real a) => a -> a -> a
mod' n d =
let dr = toRational d
nr = toRational n
qt = toRational $ floor (nr / dr)
in fromRational (nr - (qt * dr))
>>= mod' 3.154831645792668e16 (2 * pi)
6.177334810858532
The advantage of a definition like this is that it yields a correct result. The disadvantages are worse performance and the additional Fractional
constraint. Perhaps it would be easier to define div''
, mod''
, and divMod''
or similar?