blob: 4217d084beb155c1bb9a5c75996603882ddeb995 [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 Heimes68f5fbe2008-02-14 08:27:37 +000049## Notes on Decimal
50## ----------------
51## Decimal has all of the methods specified by the Real abc, but it should
52## not be registered as a Real because decimals do not interoperate with
53## binary floats.
Christian Heimes0bd4e112008-02-12 22:59:25 +000054##
55## Decimal has some of the characteristics of Integrals. It provides
56## logical operations but not as operators. The logical operations only apply
57## to a subset of decimals (those that are non-negative, have a zero exponent,
58## and have digits that are only 0 or 1). It does provide __long__() and
59## a three argument form of __pow__ that includes exactness guarantees.
60## It does not provide an __index__() method.
61##
62## Depending on context, decimal operations may be exact or inexact.
63##
64## When decimal is run in a context with small precision and automatic rounding,
65## it is Inexact. See the "Floating point notes" section of the decimal docs
66## for an example of losing the associative and distributive properties of
67## addition.
68##
69## When decimal is used for high precision integer arithmetic, it is Exact.
70## When the decimal used as fixed-point, it is Exact.
71## When it is run with sufficient precision, it is Exact.
72## When the decimal.Inexact trap is set, decimal operations are Exact.
73## For an example, see the float_to_decimal() recipe in the "Decimal FAQ"
74## section of the docs -- it shows an how traps are used in conjunction
75## with variable precision to reliably achieve exact results.
76
Guido van Rossum1daf9542007-08-30 17:45:54 +000077class Complex(Number):
78 """Complex defines the operations that work on the builtin complex type.
79
80 In short, those are: a conversion to complex, .real, .imag, +, -,
81 *, /, abs(), .conjugate, ==, and !=.
82
83 If it is given heterogenous arguments, and doesn't have special
84 knowledge about them, it should fall back to the builtin complex
85 type as described below.
86 """
87
88 @abstractmethod
89 def __complex__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000090 """Return a builtin complex instance. Called for complex(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +000091
Jeffrey Yasskin9893de12008-01-17 07:36:30 +000092 def __bool__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +000093 """True if self != 0. Called for bool(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +000094 return self != 0
95
96 @abstractproperty
97 def real(self):
98 """Retrieve the real component of this number.
99
100 This should subclass Real.
101 """
102 raise NotImplementedError
103
104 @abstractproperty
105 def imag(self):
106 """Retrieve the real component of this number.
107
108 This should subclass Real.
109 """
110 raise NotImplementedError
111
112 @abstractmethod
113 def __add__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000114 """self + other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000115 raise NotImplementedError
116
117 @abstractmethod
118 def __radd__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000119 """other + self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000120 raise NotImplementedError
121
122 @abstractmethod
123 def __neg__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000124 """-self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000125 raise NotImplementedError
126
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000127 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +0000128 def __pos__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000129 """+self"""
Guido van Rossumd4256302007-12-06 17:45:33 +0000130 raise NotImplementedError
Guido van Rossum1daf9542007-08-30 17:45:54 +0000131
132 def __sub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000133 """self - other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000134 return self + -other
135
136 def __rsub__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000137 """other - self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000138 return -self + other
139
140 @abstractmethod
141 def __mul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000142 """self * other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000143 raise NotImplementedError
144
145 @abstractmethod
146 def __rmul__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000147 """other * self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000148 raise NotImplementedError
149
150 @abstractmethod
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000151 def __truediv__(self, other):
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000152 """self / other: Should promote to float when necessary."""
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000153 raise NotImplementedError
154
155 @abstractmethod
156 def __rtruediv__(self, other):
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000157 """other / self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000158 raise NotImplementedError
159
160 @abstractmethod
161 def __pow__(self, exponent):
Guido van Rossumd4256302007-12-06 17:45:33 +0000162 """self**exponent; should promote to float or complex when necessary."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000163 raise NotImplementedError
164
165 @abstractmethod
166 def __rpow__(self, base):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000167 """base ** self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000168 raise NotImplementedError
169
170 @abstractmethod
171 def __abs__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000172 """Returns the Real distance from 0. Called for abs(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000173 raise NotImplementedError
174
175 @abstractmethod
176 def conjugate(self):
177 """(x+y*i).conjugate() returns (x-y*i)."""
178 raise NotImplementedError
179
180 @abstractmethod
181 def __eq__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000182 """self == other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000183 raise NotImplementedError
184
Christian Heimes77c02eb2008-02-09 02:18:51 +0000185 def __ne__(self, other):
186 """self != other"""
187 # The default __ne__ doesn't negate __eq__ until 3.0.
188 return not (self == other)
Guido van Rossum1daf9542007-08-30 17:45:54 +0000189
190Complex.register(complex)
191
192
193class Real(Complex):
194 """To Complex, Real adds the operations that work on real numbers.
195
196 In short, those are: a conversion to float, trunc(), divmod,
197 %, <, <=, >, and >=.
198
199 Real also provides defaults for the derived operations.
200 """
201
202 @abstractmethod
203 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000204 """Any Real can be converted to a native float object.
205
206 Called for float(self)."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000207 raise NotImplementedError
208
209 @abstractmethod
210 def __trunc__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000211 """trunc(self): Truncates self to an Integral.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000212
213 Returns an Integral i such that:
Guido van Rossumd4256302007-12-06 17:45:33 +0000214 * i>0 iff self>0;
215 * abs(i) <= abs(self);
216 * for any Integral j satisfying the first two conditions,
217 abs(i) >= abs(j) [i.e. i has "maximal" abs among those].
218 i.e. "truncate towards 0".
219 """
220 raise NotImplementedError
221
222 @abstractmethod
223 def __floor__(self):
224 """Finds the greatest Integral <= self."""
225 raise NotImplementedError
226
227 @abstractmethod
228 def __ceil__(self):
229 """Finds the least Integral >= self."""
230 raise NotImplementedError
231
232 @abstractmethod
233 def __round__(self, ndigits:"Integral"=None):
234 """Rounds self to ndigits decimal places, defaulting to 0.
235
236 If ndigits is omitted or None, returns an Integral, otherwise
237 returns a Real. Rounds half toward even.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000238 """
239 raise NotImplementedError
240
241 def __divmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000242 """divmod(self, other): The pair (self // other, self % other).
Guido van Rossum1daf9542007-08-30 17:45:54 +0000243
244 Sometimes this can be computed faster than the pair of
245 operations.
246 """
247 return (self // other, self % other)
248
249 def __rdivmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000250 """divmod(other, self): The pair (self // other, self % other).
Guido van Rossum1daf9542007-08-30 17:45:54 +0000251
252 Sometimes this can be computed faster than the pair of
253 operations.
254 """
255 return (other // self, other % self)
256
257 @abstractmethod
258 def __floordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000259 """self // other: The floor() of self/other."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000260 raise NotImplementedError
261
262 @abstractmethod
263 def __rfloordiv__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000264 """other // self: The floor() of other/self."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000265 raise NotImplementedError
266
267 @abstractmethod
268 def __mod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000269 """self % other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000270 raise NotImplementedError
271
272 @abstractmethod
273 def __rmod__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000274 """other % self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000275 raise NotImplementedError
276
277 @abstractmethod
278 def __lt__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000279 """self < other
280
281 < on Reals defines a total ordering, except perhaps for NaN."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000282 raise NotImplementedError
283
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000284 @abstractmethod
Guido van Rossum1daf9542007-08-30 17:45:54 +0000285 def __le__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000286 """self <= other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000287 raise NotImplementedError
288
289 # Concrete implementations of Complex abstract methods.
290 def __complex__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000291 """complex(self) == complex(float(self), 0)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000292 return complex(float(self))
293
294 @property
295 def real(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000296 """Real numbers are their real component."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000297 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000298
299 @property
300 def imag(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000301 """Real numbers have no imaginary component."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000302 return 0
303
304 def conjugate(self):
305 """Conjugate is a no-op for Reals."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000306 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000307
308Real.register(float)
309
310
311class Rational(Real, Exact):
312 """.numerator and .denominator should be in lowest terms."""
313
314 @abstractproperty
315 def numerator(self):
316 raise NotImplementedError
317
318 @abstractproperty
319 def denominator(self):
320 raise NotImplementedError
321
322 # Concrete implementation of Real's conversion to float.
323 def __float__(self):
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000324 """float(self) = self.numerator / self.denominator
325
326 It's important that this conversion use the integer's "true"
327 division rather than casting one side to float before dividing
328 so that ratios of huge integers convert without overflowing.
329
330 """
Guido van Rossum1daf9542007-08-30 17:45:54 +0000331 return self.numerator / self.denominator
332
333
334class Integral(Rational):
335 """Integral adds a conversion to int and the bit-string operations."""
336
337 @abstractmethod
338 def __int__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000339 """int(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000340 raise NotImplementedError
341
342 def __index__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000343 """index(self)"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000344 return int(self)
345
346 @abstractmethod
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000347 def __pow__(self, exponent, modulus=None):
Guido van Rossum1daf9542007-08-30 17:45:54 +0000348 """self ** exponent % modulus, but maybe faster.
349
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000350 Accept the modulus argument if you want to support the
351 3-argument version of pow(). Raise a TypeError if exponent < 0
352 or any argument isn't Integral. Otherwise, just implement the
353 2-argument version described in Complex.
Guido van Rossum1daf9542007-08-30 17:45:54 +0000354 """
355 raise NotImplementedError
356
357 @abstractmethod
358 def __lshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000359 """self << other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000360 raise NotImplementedError
361
362 @abstractmethod
363 def __rlshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000364 """other << self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000365 raise NotImplementedError
366
367 @abstractmethod
368 def __rshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000369 """self >> other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000370 raise NotImplementedError
371
372 @abstractmethod
373 def __rrshift__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000374 """other >> self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000375 raise NotImplementedError
376
377 @abstractmethod
378 def __and__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000379 """self & other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000380 raise NotImplementedError
381
382 @abstractmethod
383 def __rand__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000384 """other & self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000385 raise NotImplementedError
386
387 @abstractmethod
388 def __xor__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000389 """self ^ other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000390 raise NotImplementedError
391
392 @abstractmethod
393 def __rxor__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000394 """other ^ self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000395 raise NotImplementedError
396
397 @abstractmethod
398 def __or__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000399 """self | other"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000400 raise NotImplementedError
401
402 @abstractmethod
403 def __ror__(self, other):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000404 """other | self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000405 raise NotImplementedError
406
407 @abstractmethod
408 def __invert__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000409 """~self"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000410 raise NotImplementedError
411
412 # Concrete implementations of Rational and Real abstract methods.
413 def __float__(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000414 """float(self) == float(int(self))"""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000415 return float(int(self))
416
417 @property
418 def numerator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000419 """Integers are their own numerators."""
Guido van Rossumd4256302007-12-06 17:45:33 +0000420 return +self
Guido van Rossum1daf9542007-08-30 17:45:54 +0000421
422 @property
423 def denominator(self):
Jeffrey Yasskin3404b3c2007-09-07 15:15:49 +0000424 """Integers have a denominator of 1."""
Guido van Rossum1daf9542007-08-30 17:45:54 +0000425 return 1
426
427Integral.register(int)