git.iko.soy/rowtype-yoga/purescript-fixed-precision
on main help sign in
Remove the EuclideanRing instance, add approxDiv instead
46090bdPhil Freeman
generated-docs/Data/Fixed.md+21−1
@@ -26,7 +26,6 @@ Eq (Fixed precision)
26Ord (Fixed precision)
26Ord (Fixed precision)
27(KnownPrecision precision) => Semiring (Fixed precision)
27(KnownPrecision precision) => Semiring (Fixed precision)
28(KnownPrecision precision) => Ring (Fixed precision)
28(KnownPrecision precision) => Ring (Fixed precision)
29−(KnownPrecision precision) => EuclideanRing (Fixed precision)
30(KnownPrecision precision) => CommutativeRing (Fixed precision)
29(KnownPrecision precision) => CommutativeRing (Fixed precision)
31```
30```
32
31
@@ -142,6 +141,27 @@ fromNumber 1.0 :: P10
142fromNumber 0.0 :: P10
141fromNumber 0.0 :: P10
143```
142```
144
143
144+#### `approxDiv`
145+
146+``` purescript
147+approxDiv :: forall precision. KnownPrecision precision => Fixed precision -> Fixed precision -> Fixed precision
148+```
149+
150+Approximate division of fixed-precision numbers.
151+
152+```
153+> fromNumber 22.0 `approxDiv` fromNumber 7.0 :: Fixed P100
154+fromNumber 3.14 :: P100
155+```
156+
157+_Note_: `Fixed` is not a `EuclideanRing` in general - it is not even
158+an integral domain, since it has non-zero zero-divisors:
159+
160+```
161+> fromNumber 0.1 * fromNumber 0.1 :: Fixed P10
162+fromNumber 0.0 :: P10
163+```
164+
145#### `Precision`
165#### `Precision`
146
166
147``` purescript
167``` purescript
src/Data/Fixed.purs+27−13
@@ -11,6 +11,7 @@ module Data.Fixed
11 , floor
11 , floor
12 , ceil
12 , ceil
13 , round
13 , round
14+ , approxDiv
14 , kind Precision
15 , kind Precision
15 , One
16 , One
16 , TenTimes
17 , TenTimes
@@ -234,6 +235,32 @@ round n = Fixed (numerator n + x) where
234 | m * BigInt.fromInt 2 >= d = d - m
235 | m * BigInt.fromInt 2 >= d = d - m
235 | otherwise = -m
236 | otherwise = -m
236
237
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+
237instance showFixed :: KnownPrecision precision => Show (Fixed precision) where
264instance showFixed :: KnownPrecision precision => Show (Fixed precision) where
238 show n =
265 show n =
239 "(fromNumber "
266 "(fromNumber "
@@ -257,17 +284,4 @@ instance semiringFixed :: KnownPrecision precision => Semiring (Fixed precision)
257instance ringFixed :: KnownPrecision precision => Ring (Fixed precision) where
284instance ringFixed :: KnownPrecision precision => Ring (Fixed precision) where
258 sub (Fixed n) (Fixed m) = Fixed (n - m)
285 sub (Fixed n) (Fixed m) = Fixed (n - m)
259
286
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−
273instance commutativeRingFixed :: KnownPrecision precision => CommutativeRing (Fixed precision)
287instance commutativeRingFixed :: KnownPrecision precision => CommutativeRing (Fixed precision)