Merged revisions 78818 via svnmerge from
[python/dscho.git] / Lib / numbers.py
blob82960f04cea276da84890435156a7810b554a672
1 # Copyright 2007 Google, Inc. All Rights Reserved.
2 # Licensed to PSF under a Contributor Agreement.
4 """Abstract Base Classes (ABCs) for numbers, according to PEP 3141.
6 TODO: Fill out more detailed documentation on the operators."""
8 from abc import ABCMeta, abstractmethod, abstractproperty
10 __all__ = ["Number", "Complex", "Real", "Rational", "Integral"]
12 class Number(metaclass=ABCMeta):
13 """All numbers inherit from this class.
15 If you just want to check if an argument x is a number, without
16 caring what kind, use isinstance(x, Number).
17 """
18 __slots__ = ()
20 # Concrete numeric types must provide their own hash implementation
21 __hash__ = None
24 ## Notes on Decimal
25 ## ----------------
26 ## Decimal has all of the methods specified by the Real abc, but it should
27 ## not be registered as a Real because decimals do not interoperate with
28 ## binary floats (i.e. Decimal('3.14') + 2.71828 is undefined). But,
29 ## abstract reals are expected to interoperate (i.e. R1 + R2 should be
30 ## expected to work if R1 and R2 are both Reals).
32 class Complex(Number):
33 """Complex defines the operations that work on the builtin complex type.
35 In short, those are: a conversion to complex, .real, .imag, +, -,
36 *, /, abs(), .conjugate, ==, and !=.
38 If it is given heterogenous arguments, and doesn't have special
39 knowledge about them, it should fall back to the builtin complex
40 type as described below.
41 """
43 __slots__ = ()
45 @abstractmethod
46 def __complex__(self):
47 """Return a builtin complex instance. Called for complex(self)."""
49 def __bool__(self):
50 """True if self != 0. Called for bool(self)."""
51 return self != 0
53 @abstractproperty
54 def real(self):
55 """Retrieve the real component of this number.
57 This should subclass Real.
58 """
59 raise NotImplementedError
61 @abstractproperty
62 def imag(self):
63 """Retrieve the real component of this number.
65 This should subclass Real.
66 """
67 raise NotImplementedError
69 @abstractmethod
70 def __add__(self, other):
71 """self + other"""
72 raise NotImplementedError
74 @abstractmethod
75 def __radd__(self, other):
76 """other + self"""
77 raise NotImplementedError
79 @abstractmethod
80 def __neg__(self):
81 """-self"""
82 raise NotImplementedError
84 @abstractmethod
85 def __pos__(self):
86 """+self"""
87 raise NotImplementedError
89 def __sub__(self, other):
90 """self - other"""
91 return self + -other
93 def __rsub__(self, other):
94 """other - self"""
95 return -self + other
97 @abstractmethod
98 def __mul__(self, other):
99 """self * other"""
100 raise NotImplementedError
102 @abstractmethod
103 def __rmul__(self, other):
104 """other * self"""
105 raise NotImplementedError
107 @abstractmethod
108 def __truediv__(self, other):
109 """self / other: Should promote to float when necessary."""
110 raise NotImplementedError
112 @abstractmethod
113 def __rtruediv__(self, other):
114 """other / self"""
115 raise NotImplementedError
117 @abstractmethod
118 def __pow__(self, exponent):
119 """self**exponent; should promote to float or complex when necessary."""
120 raise NotImplementedError
122 @abstractmethod
123 def __rpow__(self, base):
124 """base ** self"""
125 raise NotImplementedError
127 @abstractmethod
128 def __abs__(self):
129 """Returns the Real distance from 0. Called for abs(self)."""
130 raise NotImplementedError
132 @abstractmethod
133 def conjugate(self):
134 """(x+y*i).conjugate() returns (x-y*i)."""
135 raise NotImplementedError
137 @abstractmethod
138 def __eq__(self, other):
139 """self == other"""
140 raise NotImplementedError
142 def __ne__(self, other):
143 """self != other"""
144 # The default __ne__ doesn't negate __eq__ until 3.0.
145 return not (self == other)
147 Complex.register(complex)
150 class Real(Complex):
151 """To Complex, Real adds the operations that work on real numbers.
153 In short, those are: a conversion to float, trunc(), divmod,
154 %, <, <=, >, and >=.
156 Real also provides defaults for the derived operations.
159 __slots__ = ()
161 @abstractmethod
162 def __float__(self):
163 """Any Real can be converted to a native float object.
165 Called for float(self)."""
166 raise NotImplementedError
168 @abstractmethod
169 def __trunc__(self):
170 """trunc(self): Truncates self to an Integral.
172 Returns an Integral i such that:
173 * i>0 iff self>0;
174 * abs(i) <= abs(self);
175 * for any Integral j satisfying the first two conditions,
176 abs(i) >= abs(j) [i.e. i has "maximal" abs among those].
177 i.e. "truncate towards 0".
179 raise NotImplementedError
181 @abstractmethod
182 def __floor__(self):
183 """Finds the greatest Integral <= self."""
184 raise NotImplementedError
186 @abstractmethod
187 def __ceil__(self):
188 """Finds the least Integral >= self."""
189 raise NotImplementedError
191 @abstractmethod
192 def __round__(self, ndigits:"Integral"=None):
193 """Rounds self to ndigits decimal places, defaulting to 0.
195 If ndigits is omitted or None, returns an Integral, otherwise
196 returns a Real. Rounds half toward even.
198 raise NotImplementedError
200 def __divmod__(self, other):
201 """divmod(self, other): The pair (self // other, self % other).
203 Sometimes this can be computed faster than the pair of
204 operations.
206 return (self // other, self % other)
208 def __rdivmod__(self, other):
209 """divmod(other, self): The pair (self // other, self % other).
211 Sometimes this can be computed faster than the pair of
212 operations.
214 return (other // self, other % self)
216 @abstractmethod
217 def __floordiv__(self, other):
218 """self // other: The floor() of self/other."""
219 raise NotImplementedError
221 @abstractmethod
222 def __rfloordiv__(self, other):
223 """other // self: The floor() of other/self."""
224 raise NotImplementedError
226 @abstractmethod
227 def __mod__(self, other):
228 """self % other"""
229 raise NotImplementedError
231 @abstractmethod
232 def __rmod__(self, other):
233 """other % self"""
234 raise NotImplementedError
236 @abstractmethod
237 def __lt__(self, other):
238 """self < other
240 < on Reals defines a total ordering, except perhaps for NaN."""
241 raise NotImplementedError
243 @abstractmethod
244 def __le__(self, other):
245 """self <= other"""
246 raise NotImplementedError
248 # Concrete implementations of Complex abstract methods.
249 def __complex__(self):
250 """complex(self) == complex(float(self), 0)"""
251 return complex(float(self))
253 @property
254 def real(self):
255 """Real numbers are their real component."""
256 return +self
258 @property
259 def imag(self):
260 """Real numbers have no imaginary component."""
261 return 0
263 def conjugate(self):
264 """Conjugate is a no-op for Reals."""
265 return +self
267 Real.register(float)
270 class Rational(Real):
271 """.numerator and .denominator should be in lowest terms."""
273 __slots__ = ()
275 @abstractproperty
276 def numerator(self):
277 raise NotImplementedError
279 @abstractproperty
280 def denominator(self):
281 raise NotImplementedError
283 # Concrete implementation of Real's conversion to float.
284 def __float__(self):
285 """float(self) = self.numerator / self.denominator
287 It's important that this conversion use the integer's "true"
288 division rather than casting one side to float before dividing
289 so that ratios of huge integers convert without overflowing.
292 return self.numerator / self.denominator
295 class Integral(Rational):
296 """Integral adds a conversion to int and the bit-string operations."""
298 __slots__ = ()
300 @abstractmethod
301 def __int__(self):
302 """int(self)"""
303 raise NotImplementedError
305 def __index__(self):
306 """index(self)"""
307 return int(self)
309 @abstractmethod
310 def __pow__(self, exponent, modulus=None):
311 """self ** exponent % modulus, but maybe faster.
313 Accept the modulus argument if you want to support the
314 3-argument version of pow(). Raise a TypeError if exponent < 0
315 or any argument isn't Integral. Otherwise, just implement the
316 2-argument version described in Complex.
318 raise NotImplementedError
320 @abstractmethod
321 def __lshift__(self, other):
322 """self << other"""
323 raise NotImplementedError
325 @abstractmethod
326 def __rlshift__(self, other):
327 """other << self"""
328 raise NotImplementedError
330 @abstractmethod
331 def __rshift__(self, other):
332 """self >> other"""
333 raise NotImplementedError
335 @abstractmethod
336 def __rrshift__(self, other):
337 """other >> self"""
338 raise NotImplementedError
340 @abstractmethod
341 def __and__(self, other):
342 """self & other"""
343 raise NotImplementedError
345 @abstractmethod
346 def __rand__(self, other):
347 """other & self"""
348 raise NotImplementedError
350 @abstractmethod
351 def __xor__(self, other):
352 """self ^ other"""
353 raise NotImplementedError
355 @abstractmethod
356 def __rxor__(self, other):
357 """other ^ self"""
358 raise NotImplementedError
360 @abstractmethod
361 def __or__(self, other):
362 """self | other"""
363 raise NotImplementedError
365 @abstractmethod
366 def __ror__(self, other):
367 """other | self"""
368 raise NotImplementedError
370 @abstractmethod
371 def __invert__(self):
372 """~self"""
373 raise NotImplementedError
375 # Concrete implementations of Rational and Real abstract methods.
376 def __float__(self):
377 """float(self) == float(int(self))"""
378 return float(int(self))
380 @property
381 def numerator(self):
382 """Integers are their own numerators."""
383 return +self
385 @property
386 def denominator(self):
387 """Integers have a denominator of 1."""
388 return 1
390 Integral.register(int)