blob: a4b7a6d260b20f0292f944d0565b3422bcb01daf [file] [log] [blame]
Guido van Rossum1daf9542007-08-30 17:45:54 +00001# Copyright 2007 Google, Inc. All Rights Reserved.
2# Licensed to PSF under a Contributor Agreement.
3
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +00004"""Abstract Base Classes (ABCs) for numbers, according to PEP 3141.
5
6TODO: Fill out more detailed documentation on the operators."""
Guido van Rossum1daf9542007-08-30 17:45:54 +00007
8from abc import ABCMeta, abstractmethod, abstractproperty
9
10__all__ = ["Number", "Exact", "Inexact",
11 "Complex", "Real", "Rational", "Integral",
12 ]
13
14
15class Number(metaclass=ABCMeta):
16 """All numbers inherit from this class.
17
18 If you just want to check if an argument x is a number, without
19 caring what kind, use isinstance(x, Number).
20 """
21
22
23class Exact(Number):
24 """Operations on instances of this type are exact.
25
26 As long as the result of a homogenous operation is of the same
27 type, you can assume that it was computed exactly, and there are
28 no round-off errors. Laws like commutativity and associativity
29 hold.
30 """
31
32Exact.register(int)
33
34
35class Inexact(Number):
36 """Operations on instances of this type are inexact.
37
38 Given X, an instance of Inexact, it is possible that (X + -X) + 3
39 == 3, but X + (-X + 3) == 0. The exact form this error takes will
40 vary by type, but it's generally unsafe to compare this type for
41 equality.
42 """
43
44Inexact.register(complex)
45Inexact.register(float)
Guido van Rossumd4256302007-12-06 17:45:33 +000046# Inexact.register(decimal.Decimal)
Guido van Rossum1daf9542007-08-30 17:45:54 +000047
48
Christian Heimes0bd4e112008-02-12 22:59:25 +000049## Notes on Decimal and it how relates to the numeric tower
50## --------------------------------------------------------
51## Decimal is Real except that it does not support rich comparisons.
52##
53## Decimal has some of the characteristics of Integrals. It provides
54## logical operations but not as operators. The logical operations only apply
55## to a subset of decimals (those that are non-negative, have a zero exponent,
56## and have digits that are only 0 or 1). It does provide __long__() and
57## a three argument form of __pow__ that includes exactness guarantees.
58## It does not provide an __index__() method.
59##
60## Depending on context, decimal operations may be exact or inexact.
61##
62## When decimal is run in a context with small precision and automatic rounding,
63## it is Inexact. See the "Floating point notes" section of the decimal docs
64## for an example of losing the associative and distributive properties of
65## addition.
66##
67## When decimal is used for high precision integer arithmetic, it is Exact.
68## When the decimal used as fixed-point, it is Exact.
69## When it is run with sufficient precision, it is Exact.
70## When the decimal.Inexact trap is set, decimal operations are Exact.
71## For an example, see the float_to_decimal() recipe in the "Decimal FAQ"
72## section of the docs -- it shows an how traps are used in conjunction
73## with variable precision to reliably achieve exact results.
74
Guido van Rossum1daf9542007-08-30 17:45:54 +000075class Complex(Number):
76 """Complex defines the operations that work on the builtin complex type.
77
78 In short, those are: a conversion to complex, .real, .imag, +, -,
79 *, /, abs(), .conjugate, ==, and !=.
80
81 If it is given heterogenous arguments, and doesn't have special
82 knowledge about them, it should fall back to the builtin complex
83 type as described below.
84 """
85
86 @abstractmethod
87 def __complex__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000088 """Return a builtin complex instance. Called for complex(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +000089
Jeffrey Yasskin9893de12008-01-17 07:36:30 +000090 def __bool__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000091 """True if self != 0. Called for bool(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +000092 return self != 0
93
94 @abstractproperty
95 def real(self):
96 """Retrieve the real component of this number.
97
98 This should subclass Real.
99 """
100 raise NotImplementedError
101
102 @abstractproperty
103 def imag(self):
104 """Retrieve the real component of this number.
105
106 This should subclass Real.
107 """
108 raise NotImplementedError
109
110 @abstractmethod
111 def __add__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000112 """self + other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000113 raise NotImplementedError
114
115 @abstractmethod
116 def __radd__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000117 """other + self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000118 raise NotImplementedError
119
120 @abstractmethod
121 def __neg__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000122 """-self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000123 raise NotImplementedError
124
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000125 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +0000126 def __pos__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000127 """+self"""
Guido van Rossumd4256302007-12-06 17:45:33 +0000128 raise NotImplementedError
Guido van Rossum1daf9542007-08-30 17:45:54 +0000129
130 def __sub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000131 """self - other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000132 return self + -other
133
134 def __rsub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000135 """other - self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000136 return -self + other
137
138 @abstractmethod
139 def __mul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000140 """self * other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000141 raise NotImplementedError
142
143 @abstractmethod
144 def __rmul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000145 """other * self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000146 raise NotImplementedError
147
148 @abstractmethod
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000149 def __truediv__(self, other):
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000150 """self / other: Should promote to float when necessary."""
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000151 raise NotImplementedError
152
153 @abstractmethod
154 def __rtruediv__(self, other):
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000155 """other / self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000156 raise NotImplementedError
157
158 @abstractmethod
159 def __pow__(self, exponent):
Guido van Rossumd4256302007-12-06 17:45:33 +0000160 """self**exponent; should promote to float or complex when necessary."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000161 raise NotImplementedError
162
163 @abstractmethod
164 def __rpow__(self, base):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000165 """base ** self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000166 raise NotImplementedError
167
168 @abstractmethod
169 def __abs__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000170 """Returns the Real distance from 0. Called for abs(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000171 raise NotImplementedError
172
173 @abstractmethod
174 def conjugate(self):
175 """(x+y*i).conjugate() returns (x-y*i)."""
176 raise NotImplementedError
177
178 @abstractmethod
179 def __eq__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000180 """self == other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000181 raise NotImplementedError
182
Christian Heimes77c02eb2008-02-09 02:18:51 +0000183 def __ne__(self, other):
184 """self != other"""
185 # The default __ne__ doesn't negate __eq__ until 3.0.
186 return not (self == other)
Guido van Rossum1daf9542007-08-30 17:45:54 +0000187
188Complex.register(complex)
189
190
191class Real(Complex):
192 """To Complex, Real adds the operations that work on real numbers.
193
194 In short, those are: a conversion to float, trunc(), divmod,
195 %, <, <=, >, and >=.
196
197 Real also provides defaults for the derived operations.
198 """
199
200 @abstractmethod
201 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000202 """Any Real can be converted to a native float object.
203
204 Called for float(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000205 raise NotImplementedError
206
207 @abstractmethod
208 def __trunc__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000209 """trunc(self): Truncates self to an Integral.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000210
211 Returns an Integral i such that:
Guido van Rossumd4256302007-12-06 17:45:33 +0000212 * i>0 iff self>0;
213 * abs(i) <= abs(self);
214 * for any Integral j satisfying the first two conditions,
215 abs(i) >= abs(j) [i.e. i has "maximal" abs among those].
216 i.e. "truncate towards 0".
217 """
218 raise NotImplementedError
219
220 @abstractmethod
221 def __floor__(self):
222 """Finds the greatest Integral <= self."""
223 raise NotImplementedError
224
225 @abstractmethod
226 def __ceil__(self):
227 """Finds the least Integral >= self."""
228 raise NotImplementedError
229
230 @abstractmethod
231 def __round__(self, ndigits:"Integral"=None):
232 """Rounds self to ndigits decimal places, defaulting to 0.
233
234 If ndigits is omitted or None, returns an Integral, otherwise
235 returns a Real. Rounds half toward even.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000236 """
237 raise NotImplementedError
238
239 def __divmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000240 """divmod(self, other): The pair (self // other, self % other).
Guido van Rossum1daf9542007-08-30 17:45:54 +0000241
242 Sometimes this can be computed faster than the pair of
243 operations.
244 """
245 return (self // other, self % other)
246
247 def __rdivmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000248 """divmod(other, self): The pair (self // other, self % other).
Guido van Rossum1daf9542007-08-30 17:45:54 +0000249
250 Sometimes this can be computed faster than the pair of
251 operations.
252 """
253 return (other // self, other % self)
254
255 @abstractmethod
256 def __floordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000257 """self // other: The floor() of self/other."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000258 raise NotImplementedError
259
260 @abstractmethod
261 def __rfloordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000262 """other // self: The floor() of other/self."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000263 raise NotImplementedError
264
265 @abstractmethod
266 def __mod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000267 """self % other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000268 raise NotImplementedError
269
270 @abstractmethod
271 def __rmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000272 """other % self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000273 raise NotImplementedError
274
275 @abstractmethod
276 def __lt__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000277 """self < other
278
279 < on Reals defines a total ordering, except perhaps for NaN."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000280 raise NotImplementedError
281
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000282 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +0000283 def __le__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000284 """self <= other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000285 raise NotImplementedError
286
287 # Concrete implementations of Complex abstract methods.
288 def __complex__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000289 """complex(self) == complex(float(self), 0)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000290 return complex(float(self))
291
292 @property
293 def real(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000294 """Real numbers are their real component."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000295 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000296
297 @property
298 def imag(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000299 """Real numbers have no imaginary component."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000300 return 0
301
302 def conjugate(self):
303 """Conjugate is a no-op for Reals."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000304 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000305
306Real.register(float)
Guido van Rossumd4256302007-12-06 17:45:33 +0000307# Real.register(decimal.Decimal)
Guido van Rossum1daf9542007-08-30 17:45:54 +0000308
309
310class Rational(Real, Exact):
311 """.numerator and .denominator should be in lowest terms."""
312
313 @abstractproperty
314 def numerator(self):
315 raise NotImplementedError
316
317 @abstractproperty
318 def denominator(self):
319 raise NotImplementedError
320
321 # Concrete implementation of Real's conversion to float.
322 def __float__(self):
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000323 """float(self) = self.numerator / self.denominator
324
325 It's important that this conversion use the integer's "true"
326 division rather than casting one side to float before dividing
327 so that ratios of huge integers convert without overflowing.
328
329 """
Guido van Rossum1daf9542007-08-30 17:45:54 +0000330 return self.numerator / self.denominator
331
332
333class Integral(Rational):
334 """Integral adds a conversion to int and the bit-string operations."""
335
336 @abstractmethod
337 def __int__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000338 """int(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000339 raise NotImplementedError
340
341 def __index__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000342 """index(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000343 return int(self)
344
345 @abstractmethod
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000346 def __pow__(self, exponent, modulus=None):
Guido van Rossum1daf9542007-08-30 17:45:54 +0000347 """self ** exponent % modulus, but maybe faster.
348
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000349 Accept the modulus argument if you want to support the
350 3-argument version of pow(). Raise a TypeError if exponent < 0
351 or any argument isn't Integral. Otherwise, just implement the
352 2-argument version described in Complex.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000353 """
354 raise NotImplementedError
355
356 @abstractmethod
357 def __lshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000358 """self << other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000359 raise NotImplementedError
360
361 @abstractmethod
362 def __rlshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000363 """other << self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000364 raise NotImplementedError
365
366 @abstractmethod
367 def __rshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000368 """self >> other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000369 raise NotImplementedError
370
371 @abstractmethod
372 def __rrshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000373 """other >> self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000374 raise NotImplementedError
375
376 @abstractmethod
377 def __and__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000378 """self & other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000379 raise NotImplementedError
380
381 @abstractmethod
382 def __rand__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000383 """other & self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000384 raise NotImplementedError
385
386 @abstractmethod
387 def __xor__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000388 """self ^ other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000389 raise NotImplementedError
390
391 @abstractmethod
392 def __rxor__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000393 """other ^ self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000394 raise NotImplementedError
395
396 @abstractmethod
397 def __or__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000398 """self | other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000399 raise NotImplementedError
400
401 @abstractmethod
402 def __ror__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000403 """other | self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000404 raise NotImplementedError
405
406 @abstractmethod
407 def __invert__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000408 """~self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000409 raise NotImplementedError
410
411 # Concrete implementations of Rational and Real abstract methods.
412 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000413 """float(self) == float(int(self))"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000414 return float(int(self))
415
416 @property
417 def numerator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000418 """Integers are their own numerators."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000419 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000420
421 @property
422 def denominator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000423 """Integers have a denominator of 1."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000424 return 1
425
426Integral.register(int)