numbers.py 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. # Copyright 2007 Google, Inc. All Rights Reserved.
  2. # Licensed to PSF under a Contributor Agreement.
  3. """Abstract Base Classes (ABCs) for numbers, according to PEP 3141.
  4. TODO: Fill out more detailed documentation on the operators."""
  5. from __future__ import division
  6. from abc import ABCMeta, abstractmethod, abstractproperty
  7. __all__ = ["Number", "Complex", "Real", "Rational", "Integral"]
  8. class Number(object):
  9. """All numbers inherit from this class.
  10. If you just want to check if an argument x is a number, without
  11. caring what kind, use isinstance(x, Number).
  12. """
  13. __metaclass__ = ABCMeta
  14. __slots__ = ()
  15. # Concrete numeric types must provide their own hash implementation
  16. __hash__ = None
  17. ## Notes on Decimal
  18. ## ----------------
  19. ## Decimal has all of the methods specified by the Real abc, but it should
  20. ## not be registered as a Real because decimals do not interoperate with
  21. ## binary floats (i.e. Decimal('3.14') + 2.71828 is undefined). But,
  22. ## abstract reals are expected to interoperate (i.e. R1 + R2 should be
  23. ## expected to work if R1 and R2 are both Reals).
  24. class Complex(Number):
  25. """Complex defines the operations that work on the builtin complex type.
  26. In short, those are: a conversion to complex, .real, .imag, +, -,
  27. *, /, abs(), .conjugate, ==, and !=.
  28. If it is given heterogenous arguments, and doesn't have special
  29. knowledge about them, it should fall back to the builtin complex
  30. type as described below.
  31. """
  32. __slots__ = ()
  33. @abstractmethod
  34. def __complex__(self):
  35. """Return a builtin complex instance. Called for complex(self)."""
  36. # Will be __bool__ in 3.0.
  37. def __nonzero__(self):
  38. """True if self != 0. Called for bool(self)."""
  39. return self != 0
  40. @abstractproperty
  41. def real(self):
  42. """Retrieve the real component of this number.
  43. This should subclass Real.
  44. """
  45. raise NotImplementedError
  46. @abstractproperty
  47. def imag(self):
  48. """Retrieve the imaginary component of this number.
  49. This should subclass Real.
  50. """
  51. raise NotImplementedError
  52. @abstractmethod
  53. def __add__(self, other):
  54. """self + other"""
  55. raise NotImplementedError
  56. @abstractmethod
  57. def __radd__(self, other):
  58. """other + self"""
  59. raise NotImplementedError
  60. @abstractmethod
  61. def __neg__(self):
  62. """-self"""
  63. raise NotImplementedError
  64. @abstractmethod
  65. def __pos__(self):
  66. """+self"""
  67. raise NotImplementedError
  68. def __sub__(self, other):
  69. """self - other"""
  70. return self + -other
  71. def __rsub__(self, other):
  72. """other - self"""
  73. return -self + other
  74. @abstractmethod
  75. def __mul__(self, other):
  76. """self * other"""
  77. raise NotImplementedError
  78. @abstractmethod
  79. def __rmul__(self, other):
  80. """other * self"""
  81. raise NotImplementedError
  82. @abstractmethod
  83. def __div__(self, other):
  84. """self / other without __future__ division
  85. May promote to float.
  86. """
  87. raise NotImplementedError
  88. @abstractmethod
  89. def __rdiv__(self, other):
  90. """other / self without __future__ division"""
  91. raise NotImplementedError
  92. @abstractmethod
  93. def __truediv__(self, other):
  94. """self / other with __future__ division.
  95. Should promote to float when necessary.
  96. """
  97. raise NotImplementedError
  98. @abstractmethod
  99. def __rtruediv__(self, other):
  100. """other / self with __future__ division"""
  101. raise NotImplementedError
  102. @abstractmethod
  103. def __pow__(self, exponent):
  104. """self**exponent; should promote to float or complex when necessary."""
  105. raise NotImplementedError
  106. @abstractmethod
  107. def __rpow__(self, base):
  108. """base ** self"""
  109. raise NotImplementedError
  110. @abstractmethod
  111. def __abs__(self):
  112. """Returns the Real distance from 0. Called for abs(self)."""
  113. raise NotImplementedError
  114. @abstractmethod
  115. def conjugate(self):
  116. """(x+y*i).conjugate() returns (x-y*i)."""
  117. raise NotImplementedError
  118. @abstractmethod
  119. def __eq__(self, other):
  120. """self == other"""
  121. raise NotImplementedError
  122. def __ne__(self, other):
  123. """self != other"""
  124. # The default __ne__ doesn't negate __eq__ until 3.0.
  125. return not (self == other)
  126. Complex.register(complex)
  127. class Real(Complex):
  128. """To Complex, Real adds the operations that work on real numbers.
  129. In short, those are: a conversion to float, trunc(), divmod,
  130. %, <, <=, >, and >=.
  131. Real also provides defaults for the derived operations.
  132. """
  133. __slots__ = ()
  134. @abstractmethod
  135. def __float__(self):
  136. """Any Real can be converted to a native float object.
  137. Called for float(self)."""
  138. raise NotImplementedError
  139. @abstractmethod
  140. def __trunc__(self):
  141. """trunc(self): Truncates self to an Integral.
  142. Returns an Integral i such that:
  143. * i>0 iff self>0;
  144. * abs(i) <= abs(self);
  145. * for any Integral j satisfying the first two conditions,
  146. abs(i) >= abs(j) [i.e. i has "maximal" abs among those].
  147. i.e. "truncate towards 0".
  148. """
  149. raise NotImplementedError
  150. def __divmod__(self, other):
  151. """divmod(self, other): The pair (self // other, self % other).
  152. Sometimes this can be computed faster than the pair of
  153. operations.
  154. """
  155. return (self // other, self % other)
  156. def __rdivmod__(self, other):
  157. """divmod(other, self): The pair (self // other, self % other).
  158. Sometimes this can be computed faster than the pair of
  159. operations.
  160. """
  161. return (other // self, other % self)
  162. @abstractmethod
  163. def __floordiv__(self, other):
  164. """self // other: The floor() of self/other."""
  165. raise NotImplementedError
  166. @abstractmethod
  167. def __rfloordiv__(self, other):
  168. """other // self: The floor() of other/self."""
  169. raise NotImplementedError
  170. @abstractmethod
  171. def __mod__(self, other):
  172. """self % other"""
  173. raise NotImplementedError
  174. @abstractmethod
  175. def __rmod__(self, other):
  176. """other % self"""
  177. raise NotImplementedError
  178. @abstractmethod
  179. def __lt__(self, other):
  180. """self < other
  181. < on Reals defines a total ordering, except perhaps for NaN."""
  182. raise NotImplementedError
  183. @abstractmethod
  184. def __le__(self, other):
  185. """self <= other"""
  186. raise NotImplementedError
  187. # Concrete implementations of Complex abstract methods.
  188. def __complex__(self):
  189. """complex(self) == complex(float(self), 0)"""
  190. return complex(float(self))
  191. @property
  192. def real(self):
  193. """Real numbers are their real component."""
  194. return +self
  195. @property
  196. def imag(self):
  197. """Real numbers have no imaginary component."""
  198. return 0
  199. def conjugate(self):
  200. """Conjugate is a no-op for Reals."""
  201. return +self
  202. Real.register(float)
  203. class Rational(Real):
  204. """.numerator and .denominator should be in lowest terms."""
  205. __slots__ = ()
  206. @abstractproperty
  207. def numerator(self):
  208. raise NotImplementedError
  209. @abstractproperty
  210. def denominator(self):
  211. raise NotImplementedError
  212. # Concrete implementation of Real's conversion to float.
  213. def __float__(self):
  214. """float(self) = self.numerator / self.denominator
  215. It's important that this conversion use the integer's "true"
  216. division rather than casting one side to float before dividing
  217. so that ratios of huge integers convert without overflowing.
  218. """
  219. return self.numerator / self.denominator
  220. class Integral(Rational):
  221. """Integral adds a conversion to long and the bit-string operations."""
  222. __slots__ = ()
  223. @abstractmethod
  224. def __long__(self):
  225. """long(self)"""
  226. raise NotImplementedError
  227. def __index__(self):
  228. """Called whenever an index is needed, such as in slicing"""
  229. return long(self)
  230. @abstractmethod
  231. def __pow__(self, exponent, modulus=None):
  232. """self ** exponent % modulus, but maybe faster.
  233. Accept the modulus argument if you want to support the
  234. 3-argument version of pow(). Raise a TypeError if exponent < 0
  235. or any argument isn't Integral. Otherwise, just implement the
  236. 2-argument version described in Complex.
  237. """
  238. raise NotImplementedError
  239. @abstractmethod
  240. def __lshift__(self, other):
  241. """self << other"""
  242. raise NotImplementedError
  243. @abstractmethod
  244. def __rlshift__(self, other):
  245. """other << self"""
  246. raise NotImplementedError
  247. @abstractmethod
  248. def __rshift__(self, other):
  249. """self >> other"""
  250. raise NotImplementedError
  251. @abstractmethod
  252. def __rrshift__(self, other):
  253. """other >> self"""
  254. raise NotImplementedError
  255. @abstractmethod
  256. def __and__(self, other):
  257. """self & other"""
  258. raise NotImplementedError
  259. @abstractmethod
  260. def __rand__(self, other):
  261. """other & self"""
  262. raise NotImplementedError
  263. @abstractmethod
  264. def __xor__(self, other):
  265. """self ^ other"""
  266. raise NotImplementedError
  267. @abstractmethod
  268. def __rxor__(self, other):
  269. """other ^ self"""
  270. raise NotImplementedError
  271. @abstractmethod
  272. def __or__(self, other):
  273. """self | other"""
  274. raise NotImplementedError
  275. @abstractmethod
  276. def __ror__(self, other):
  277. """other | self"""
  278. raise NotImplementedError
  279. @abstractmethod
  280. def __invert__(self):
  281. """~self"""
  282. raise NotImplementedError
  283. # Concrete implementations of Rational and Real abstract methods.
  284. def __float__(self):
  285. """float(self) == float(long(self))"""
  286. return float(long(self))
  287. @property
  288. def numerator(self):
  289. """Integers are their own numerators."""
  290. return +self
  291. @property
  292. def denominator(self):
  293. """Integers have a denominator of 1."""
  294. return 1
  295. Integral.register(int)
  296. Integral.register(long)