diff options
author | Jakob Kaivo <jkk@ung.org> | 2022-03-04 12:32:20 -0500 |
---|---|---|
committer | Jakob Kaivo <jkk@ung.org> | 2022-03-04 12:32:20 -0500 |
commit | 55f277e77428d7423ae906a8e1f1324d35b07a7d (patch) | |
tree | 5c1c04703dff89c46b349025d2d3ec88ea9b3819 /miralib/ex/rational.m |
import Miranda 2.066 from upstream
Diffstat (limited to 'miralib/ex/rational.m')
-rw-r--r-- | miralib/ex/rational.m | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/miralib/ex/rational.m b/miralib/ex/rational.m new file mode 100644 index 0000000..8b432d1 --- /dev/null +++ b/miralib/ex/rational.m @@ -0,0 +1,56 @@ +||rational numbers as an abstract data type, say +|| %include <ex/rat> +||to include this in one of your own scripts. Quoting the filename in +||this form makes the %include directive work from any directory. + +abstype rational +with ratio :: num -> num -> rational + mkrat :: num->rational + rplus, rminus, rtimes, rdiv :: rational -> rational -> rational + rpow :: num -> rational -> rational + numerator, denominator :: rational -> num + rparts :: rational -> (num,num) + showrational :: rational -> [char] + +rational == (num,num) + +||a rational is represented as a pair of integers +||note that rationals are kept in their lowest terms, with positive +||denominator, and (0,1) is the unique representation of zero + +ratio p q = error "illegal ratio", if q=0\/~integer p\/~integer q + = ratio (-p) (-q), if q<0 + = (0,1), if p=0 + = (p div h,q div h), otherwise + where + h = hcf (abs p) q + hcf a b = hcf b a, if a>b + = b, if a=0 + = hcf (b mod a) a, otherwise + +mkrat n = ratio n 1, if integer n + = error ("mkrat "++shownum n), otherwise + +(a,b) $rplus (c,d) = ratio (a*d+c*b) (b*d) +(a,b) $rminus (c,d) = ratio (a*d-c*b) (b*d) +(a,b) $rtimes (c,d) = ratio (a*c) (b*d) +(a,b) $rdiv (c,d) = ratio (a*d) (b*c) + +rpow 0 x = (1,1) +rpow n x = thing, if n mod 2 = 0 + = x $rtimes thing, otherwise + where + thing = rpow (n div 2) (x $rtimes x) + +numerator = fst +denominator = snd +rparts = id + +showrational (a,b) = "(ratio "++shownum1 a++" "++shownum1 b++")" +shownum1 n = "("++shownum n++")", if n<0 + = shownum n, otherwise + +||Attempts to print a rational will automatically pick up the function +||called showrational - see manual section on abstract data types. Note +||that we have chosen to print rationals in such a way that Miranda can +||read them back in again at the same type. |