数値を範囲 "[0, 除数)" で保持する合同式向け数値クラス

# 剰余数を保持する数値クラス

a, p を整数として

```python:
v = a % p
```
p と v の情報を保持し、各演算子を使うためのクラスです。例えば、次の計算は

```math:
7754077^{16307003-1} \equiv 1 \pmod{16307003}
```

```python:
>>> a = ModNumber(16307003, 7754077)
>>> a
(7754077 % 16307003)
>>> a ** (a.divisor - 1)
(1 % 16307003)
```

となります。保持される値 (a.value) は "[0, a.divisor)" です。

クラスが \_\_repr\_\_() 関数で返す文字列は
　　"(value % divisor)"
形式です。

因みに「<code>7754077 ** (16307003 - 1) % 16307003</code>」の実行はやめましょう。


# プログラム

```python:modnum.py
from numbers import Integral


class ModNumber(Integral):
    def __init__(self, divisor, value=0):
        if divisor <= 0:
            raise ArithmeticError
        self.divisor = int(divisor)
        self.set_value(value)

    def get_divisor(self): return self.divisor
    def get_value(self): return self.value

    def set_value(self, value):
        divisor = self.divisor
        value = int(value) % divisor
        if value < 0:
            value += divisor
        self.value = value
        return self

    # override

    def __int__(self): return self.value
    def __repr__(self): return '(%d %% %d)' % (self.value, self.divisor)
    def __str__(self): return self.__repr__()

    def __eq__(self, other):
        if type(other) == ModNumber:
            if self.divisor != other.divisor:
                raise ArithmeticError
            value = other.value
        else:
            value = int(value)
        return (((self.value - value) % self.divisor) == 0)

    def __lt__(self, other): raise NotImplemented
    def __le__(self, other): raise NotImplemented

    def __neg__(self): return ModNumber(self.divisor, -self.value)
    def __pos__(self): return ModNumber(self.divisor, +self.value)
    def __invert__(self): raise NotImplemented

    def __add__(self, other): return ModNumber(self.divisor, self.value + other)
    def __sub__(self, other): return ModNumber(self.divisor, self.value - other)
    def __mul__(self, other): return ModNumber(self.divisor, self.value * other)
    def __pow__(self, other): return ModNumber(self.divisor, pow(self.value, other, self.divisor))

    def __divmod__(self, other):
        l, d = self.value, self.divisor
        return tuple(ModNumber(d, t) for t in (l / other, l % other))

    def __truediv__(self, other): return ModNumber(self.divisor, self.value / other)
    def __floordiv__(self, other): return ModNumber(self.divisor, self.value // other)
    def __mod__(self, other): return ModNumber(self.divisor, self.value % other)

    def __and__(self, other): return ModNumber(self.divisor, self.value & int(other))
    def __xor__(self, other): return ModNumber(self.divisor, self.value ^ int(other))
    def __or__(self, other): return ModNumber(self.divisor, self.value | int(other))

    def __lshift__(self, other): return self * ModNumber(self.divisor, 2)**other
    def __rshift__(self, other): return ModNumber(self.divisor, self.value >> int(other))

    def __radd__(self, other): return other + self.value
    def __rsub__(self, other): return other - self.value
    def __rmul__(self, other): return other * self.value
    def __rmod__(self, other): return other % self.value
    def __rtruediv__(self, other): return other % self.value
    def __rfloordiv__(self, other): return other // self.value
    def __rpow__(self, other): return other ** self.value

    def __rand__(self, other): return other & self.value
    def __rxor__(self, other): return other ^ self.value
    def __ror__(self, other): return other | self.value

    def __rlshift__(self, other): return other << self.value
    def __rrshift__(self, other): return other >> self.value

    def __iadd__(self, other): return self.set_value(self.value + int(other))
    def __isub__(self, other): return self.set_value(self.value - int(other))
    def __imul__(self, other): return self.set_value(self.value * other)
    def __itruediv__(self, other): return self.set_value(self.value // other)
    def __imod__(self, other): return self.set_value(self.value % other)

    def __abs__(self): return self
    def __ceil__(self): return self
    def __floor__(self): return self
    def __round__(self): return self
    def __trunc__(self): return self
```