chiark / gitweb /
catacomb/__init__.py: Slightly cheesy rational arithmetic.
authorMark Wooding <mdw@distorted.org.uk>
Fri, 27 Feb 2015 14:41:18 +0000 (14:41 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Fri, 27 Feb 2015 14:45:00 +0000 (14:45 +0000)
Invoked from MP exact division.

catacomb/__init__.py

index 93f66da2287ecac37e9c1beaa96b53d456c39415..6ed992ed07be2ccba238a4d25539c48f0edd4774 100644 (file)
@@ -99,6 +99,52 @@ bytes = ByteString.fromhex
 ###--------------------------------------------------------------------------
 ### Multiprecision integers and binary polynomials.
 
+def _split_rat(x):
+  if isinstance(x, Rat): return x._n, x._d
+  else: return x, 1
+class Rat (object):
+  def __new__(cls, a, b):
+    a, b = MP(a), MP(b)
+    q, r = divmod(a, b)
+    if r == 0: return q
+    g = b.gcd(r)
+    me = super(Rat, cls).__new__(cls)
+    me._n = a//g
+    me._d = b//g
+    return me
+  @property
+  def numer(me): return me._n
+  @property
+  def denom(me): return me._d
+  def __str__(me): return '%s/%s' % (me._n, me._d)
+  def __repr__(me): return 'Rat(%s, %s)' % (me._n, me._d)
+
+  def __add__(me, you):
+    n, d = _split_rat(you)
+    return Rat(me._n*d + n*me._d, d*me._d)
+  __radd__ = __add__
+  def __sub__(me, you):
+    n, d = _split_rat(you)
+    return Rat(me._n*d - n*me._d, d*me._d)
+  def __rsub__(me, you):
+    n, d = _split_rat(you)
+    return Rat(n*me._d - me._n*d, d*me._d)
+  def __mul__(me, you):
+    n, d = _split_rat(you)
+    return Rat(me._n*n, me._d*d)
+  def __div__(me, you):
+    n, d = _split_rat(you)
+    return Rat(me._n*d, me._d*n)
+  def __rdiv__(me, you):
+    n, d = _split_rat(you)
+    return Rat(me._d*n, me._n*d)
+  def __cmp__(me, you):
+    n, d = _split_rat(you)
+    return cmp(me._n*d, n*me._d)
+  def __rcmp__(me, you):
+    n, d = _split_rat(you)
+    return cmp(n*me._d, me._n*d)
+
 class _tmp:
   def negp(x): return x < 0
   def posp(x): return x > 0
@@ -108,6 +154,8 @@ class _tmp:
   def mont(x): return MPMont(x)
   def barrett(x): return MPBarrett(x)
   def reduce(x): return MPReduce(x)
+  def __div__(me, you): return Rat(me, you)
+  def __rdiv__(me, you): return Rat(you, me)
 _augment(MP, _tmp)
 
 class _tmp: