| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- from .euclidean import *
- from .numbertype import *
- # so all IntegersModP are instances of the same base class
- class _Modular(FieldElement):
- pass
- @memoize
- def IntegersModP(p):
- # assume p is prime
- class IntegerModP(_Modular):
- def __init__(self, n):
- try:
- self.n = int(n) % IntegerModP.p
- except:
- raise TypeError("Can't cast type %s to %s in __init__" %
- (type(n).__name__, type(self).__name__))
- self.field = IntegerModP
- @typecheck
- def __add__(self, other):
- return IntegerModP(self.n + other.n)
- @typecheck
- def __sub__(self, other):
- return IntegerModP(self.n - other.n)
- @typecheck
- def __mul__(self, other):
- return IntegerModP(self.n * other.n)
- def __neg__(self):
- return IntegerModP(-self.n)
- @typecheck
- def __eq__(self, other):
- return isinstance(other, IntegerModP) and self.n == other.n
- @typecheck
- def __ne__(self, other):
- return isinstance(other, IntegerModP) is False or self.n != other.n
- @typecheck
- def __divmod__(self, divisor):
- q,r = divmod(self.n, divisor.n)
- return (IntegerModP(q), IntegerModP(r))
- def inverse(self):
- # need to use the division algorithm *as integers* because we're
- # doing it on the modulus itself (which would otherwise be zero)
- x,y,d = extendedEuclideanAlgorithm(self.n, self.p)
- if d != 1:
- raise Exception("Error: p is not prime in %s!" % (self.__name__))
- return IntegerModP(x)
- def __abs__(self):
- return abs(self.n)
- def __str__(self):
- return str(self.n)
- def __repr__(self):
- return '%d (mod %d)' % (self.n, self.p)
- def __int__(self):
- return self.n
- def __hash__(self):
- return hash((self.n, self.p))
- IntegerModP.p = p
- IntegerModP.__name__ = 'Z/%d' % (p)
- IntegerModP.englishName = 'IntegersMod%d' % (p)
- return IntegerModP
- if __name__ == "__main__":
- mod7 = IntegersModP(7)
|