>>> n = 256>>> n.to_bytes(length=1, byteorder="big")Traceback (most recent call last): File "<stdin>", line 1, in <module>OverflowError: int too big to convert
例如,考虑下面的类 ExtendedInteger,它实现了 a+bp 形式的数字,其中 a和 b 是整数,p 是素数(请注意,类不强制素数):
import mathimport numbers class ExtendedInteger(numbers.Real): def __init__(self, a, b, p = 2) -> None: self.a = a self.b = b self.p = p self._val = a + (b * math.sqrt(p)) def __repr__(self): return f"{self.__class__.__name__}({self.a}, {self.b}, {self.p})" def __str__(self): return f"{self.a} + {self.b}√{self.p}" def __trunc__(self): return int(self._val) def __float__(self): return float(self._val) def __hash__(self): return hash(float(self._val)) def __floor__(self): return math.floor(self._val) def __ceil__(self): return math.ceil(self._val) def __round__(self, ndigits=None): return round(self._val, ndigits=ndigits) def __abs__(self): return abs(self._val) def __floordiv__(self, other): return self._val // other def __rfloordiv__(self, other): return other // self._val def __truediv__(self, other): return self._val / other def __rtruediv__(self, other): return other / self._val def __mod__(self, other): return self._val % other def __rmod__(self, other): return other % self._val def __lt__(self, other): return self._val < other def __le__(self, other): return self._val <= other def __eq__(self, other): return float(self) == float(other) def __neg__(self): return ExtendedInteger(-self.a, -self.b, self.p) def __pos__(self): return ExtendedInteger(+self.a, +self.b, self.p) def __add__(self, other): if isinstance(other, ExtendedInteger): # If both instances have the same p value, # return a new ExtendedInteger instance if self.p == other.p: new_a = self.a + other.a new_b = self.b + other.b return ExtendedInteger(new_a, new_b, self.p) # Otherwise return a float else: return self._val + other._val # If other is integral, add other to self's a value elif isinstance(other, numbers.Integral): new_a = self.a + other return ExtendedInteger(new_a, self.b, self.p) # If other is real, return a float elif isinstance(other, numbers.Real): return self._val + other._val # If other is of unknown type, let other determine # what to do else: return NotImplemented def __radd__(self, other): # Addition is commutative so defer to __add__ return self.__add__(other) def __mul__(self, other): if isinstance(other, ExtendedInteger): # If both instances have the same p value, # return a new ExtendedInteger instance if self.p == other.p: new_a = (self.a * other.a) + (self.b * other.b * self.p) new_b = (self.a * other.b) + (self.b * other.a) return ExtendedInteger(new_a, new_b, self.p) # Otherwise, return a float else: return self._val * other._val # If other is integral, multiply self's a and b by other elif isinstance(other, numbers.Integral): new_a = self.a * other new_b = self.b * other return ExtendedInteger(new_a, new_b, self.p) # If other is real, return a float elif isinstance(other, numbers.Real): return self._val * other # If other is of unknown type, let other determine # what to do else: return NotImplemented def __rmul__(self, other): # Multiplication is commutative so defer to __mul__ return self.__mul__(other) def __pow__(self, exponent): return self._val ** exponent def __rpow__(self, base): return base ** self._val
复制代码
您需要实现许多 dunder 方法以确保具体类型实现 Real 接口。您还必须考虑 .__add__() 和 .__mul__() 等方法如何与其他 Real 类型交互。
实现 ExtendedInteger 后,您现在可以执行以下操作:
>>> a = ExtendedInteger(1, 2)>>> b = ExtendedInteger(2, 3) >>> aExtendedInteger(1, 2, 2) >>> # Check that a is a Number>>> isinstance(a, numbers.Number)True >>> # Check that a is Real>>> isinstance(a, numbers.Real)True >>> print(a)1 + 2√2 >>> a * bExtendedInteger(14, 7, 2) >>> print(a * b)14 + 7√2 >>> float(a)3.8284271247461903
评论