@@ -11,6 +11,7 @@ module Data.Fixed
1111 , floor
1212 , ceil
1313 , round
14+ , approxDiv
1415 , kind Precision
1516 , One
1617 , TenTimes
@@ -234,6 +235,32 @@ round n = Fixed (numerator n + x) where
234235 | m * BigInt.fromInt 2 >= d = d - m
235236 | otherwise = -m
236237
238+-- | Approximate division of fixed-precision numbers.
239+-- |
240+-- | ```
241+-- | > fromNumber 22.0 `approxDiv` fromNumber 7.0 :: Fixed P100
242+-- | fromNumber 3.14 :: P100
243+-- | ```
244+-- |
245+-- | _Note_: `Fixed` is not a `EuclideanRing` in general - it is not even
246+-- | an integral domain, since it has non-zero zero-divisors:
247+-- |
248+-- | ```
249+-- | > fromNumber 0.1 * fromNumber 0.1 :: Fixed P10
250+-- | fromNumber 0.0 :: P10
251+-- | ```
252+approxDiv
253+ :: forall precision
254+ . KnownPrecision precision
255+ => Fixed precision
256+ -> Fixed precision
257+ -> Fixed precision
258+approxDiv a b = Fixed (x * n / y)
259+ where
260+ x = numerator a
261+ y = numerator b
262+ n = BigInt.fromInt (denominator a)
263+
237264instance showFixed :: KnownPrecision precision => Show (Fixed precision) where
238265 show n =
239266 "(fromNumber "
@@ -257,17 +284,4 @@ instance semiringFixed :: KnownPrecision precision => Semiring (Fixed precision)
257284instance ringFixed :: KnownPrecision precision => Ring (Fixed precision) where
258285 sub (Fixed n) (Fixed m) = Fixed (n - m)
259286
260−instance euclideanRingFixed :: KnownPrecision precision => EuclideanRing (Fixed precision) where
261− div a b = Fixed (x * n / y)
262− where
263− x = numerator a
264− y = numerator b
265− n = BigInt.fromInt (denominator a)
266− mod a b = Fixed (((x * n) `mod` y) / n)
267− where
268− x = numerator a
269− y = numerator b
270− n = BigInt.fromInt (denominator a)
271− degree = degree <<< numerator
272−
273287instance commutativeRingFixed :: KnownPrecision precision => CommutativeRing (Fixed precision)