### Multiprecision integers and binary polynomials.
def _split_rat(x):
- if isinstance(x, Rat): return x._n, x._d
+ if isinstance(x, BaseRat): return x._n, x._d
else: return x, 1
-class Rat (object):
+class BaseRat (object):
+ """Base class implementing fields of fractions over Euclidean domains."""
def __new__(cls, a, b):
- a, b = MP(a), MP(b)
+ a, b = cls.RING(a), cls.RING(b)
q, r = divmod(a, b)
if r == 0: return q
g = b.gcd(r)
- me = super(Rat, cls).__new__(cls)
+ me = super(BaseRat, cls).__new__(cls)
me._n = a//g
me._d = b//g
return me
@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 __repr__(me): return '%s(%s, %s)' % (type(me).__name__, me._n, me._d)
def __add__(me, you):
n, d = _split_rat(you)
- return Rat(me._n*d + n*me._d, d*me._d)
+ return type(me)(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)
+ return type(me)(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)
+ return type(me)(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)
+ return type(me)(me._n*n, me._d*d)
def __div__(me, you):
n, d = _split_rat(you)
- return Rat(me._n*d, me._d*n)
+ return type(me)(me._n*d, me._d*n)
def __rdiv__(me, you):
n, d = _split_rat(you)
- return Rat(me._d*n, me._n*d)
+ return type(me)(me._d*n, me._n*d)
def __cmp__(me, you):
n, d = _split_rat(you)
- return cmp(me._n*d, n*me._d)
+ return type(me)(me._n*d, n*me._d)
def __rcmp__(me, you):
n, d = _split_rat(you)
return cmp(n*me._d, me._n*d)
+class IntRat (BaseRat):
+ RING = MP
+
+class GFRat (BaseRat):
+ RING = GF
+
class _tmp:
def negp(x): return x < 0
def posp(x): return x > 0
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)
+ def __div__(me, you): return IntRat(me, you)
+ def __rdiv__(me, you): return IntRat(you, me)
_augment(MP, _tmp)
class _tmp:
def halftrace(x, y): return x.reduce().halftrace(y)
def modsqrt(x, y): return x.reduce().sqrt(y)
def quadsolve(x, y): return x.reduce().quadsolve(y)
+ def __div__(me, you): return GFRat(me, you)
+ def __rdiv__(me, you): return GFRat(you, me)
_augment(GF, _tmp)
class _tmp: