Merged revisions 65810 via svnmerge from
[python/dscho.git] / Lib / numbers.py
blob827c25379ff8cb21f06310b9f956cd3451c1be09
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 # Concrete numeric types must provide their own hash implementation
19 __hash__ = None
22 ## Notes on Decimal
23 ## ----------------
24 ## Decimal has all of the methods specified by the Real abc, but it should
25 ## not be registered as a Real because decimals do not interoperate with
26 ## binary floats (i.e. Decimal('3.14') + 2.71828 is undefined). But,
27 ## abstract reals are expected to interoperate (i.e. R1 + R2 should be
28 ## expected to work if R1 and R2 are both Reals).
30 class Complex(Number):
31 """Complex defines the operations that work on the builtin complex type.
33 In short, those are: a conversion to complex, .real, .imag, +, -,
34 *, /, abs(), .conjugate, ==, and !=.
36 If it is given heterogenous arguments, and doesn't have special
37 knowledge about them, it should fall back to the builtin complex
38 type as described below.
39 """
41 @abstractmethod
42 def __complex__(self):
43 """Return a builtin complex instance. Called for complex(self)."""
45 def __bool__(self):
46 """True if self != 0. Called for bool(self)."""
47 return self != 0
49 @abstractproperty
50 def real(self):
51 """Retrieve the real component of this number.
53 This should subclass Real.
54 """
55 raise NotImplementedError
57 @abstractproperty
58 def imag(self):
59 """Retrieve the real component of this number.
61 This should subclass Real.
62 """
63 raise NotImplementedError
65 @abstractmethod
66 def __add__(self, other):
67 """self + other"""
68 raise NotImplementedError
70 @abstractmethod
71 def __radd__(self, other):
72 """other + self"""
73 raise NotImplementedError
75 @abstractmethod
76 def __neg__(self):
77 """-self"""
78 raise NotImplementedError
80 @abstractmethod
81 def __pos__(self):
82 """+self"""
83 raise NotImplementedError
85 def __sub__(self, other):
86 """self - other"""
87 return self + -other
89 def __rsub__(self, other):
90 """other - self"""
91 return -self + other
93 @abstractmethod
94 def __mul__(self, other):
95 """self * other"""
96 raise NotImplementedError
98 @abstractmethod
99 def __rmul__(self, other):
100 """other * self"""
101 raise NotImplementedError
103 @abstractmethod
104 def __truediv__(self, other):
105 """self / other: Should promote to float when necessary."""
106 raise NotImplementedError
108 @abstractmethod
109 def __rtruediv__(self, other):
110 """other / self"""
111 raise NotImplementedError
113 @abstractmethod
114 def __pow__(self, exponent):
115 """self**exponent; should promote to float or complex when necessary."""
116 raise NotImplementedError
118 @abstractmethod
119 def __rpow__(self, base):
120 """base ** self"""
121 raise NotImplementedError
123 @abstractmethod
124 def __abs__(self):
125 """Returns the Real distance from 0. Called for abs(self)."""
126 raise NotImplementedError
128 @abstractmethod
129 def conjugate(self):
130 """(x+y*i).conjugate() returns (x-y*i)."""
131 raise NotImplementedError
133 @abstractmethod
134 def __eq__(self, other):
135 """self == other"""
136 raise NotImplementedError
138 def __ne__(self, other):
139 """self != other"""
140 # The default __ne__ doesn't negate __eq__ until 3.0.
141 return not (self == other)
143 Complex.register(complex)
146 class Real(Complex):
147 """To Complex, Real adds the operations that work on real numbers.
149 In short, those are: a conversion to float, trunc(), divmod,
150 %, <, <=, >, and >=.
152 Real also provides defaults for the derived operations.
155 @abstractmethod
156 def __float__(self):
157 """Any Real can be converted to a native float object.
159 Called for float(self)."""
160 raise NotImplementedError
162 @abstractmethod
163 def __trunc__(self):
164 """trunc(self): Truncates self to an Integral.
166 Returns an Integral i such that:
167 * i>0 iff self>0;
168 * abs(i) <= abs(self);
169 * for any Integral j satisfying the first two conditions,
170 abs(i) >= abs(j) [i.e. i has "maximal" abs among those].
171 i.e. "truncate towards 0".
173 raise NotImplementedError
175 @abstractmethod
176 def __floor__(self):
177 """Finds the greatest Integral <= self."""
178 raise NotImplementedError
180 @abstractmethod
181 def __ceil__(self):
182 """Finds the least Integral >= self."""
183 raise NotImplementedError
185 @abstractmethod
186 def __round__(self, ndigits:"Integral"=None):
187 """Rounds self to ndigits decimal places, defaulting to 0.
189 If ndigits is omitted or None, returns an Integral, otherwise
190 returns a Real. Rounds half toward even.
192 raise NotImplementedError
194 def __divmod__(self, other):
195 """divmod(self, other): The pair (self // other, self % other).
197 Sometimes this can be computed faster than the pair of
198 operations.
200 return (self // other, self % other)
202 def __rdivmod__(self, other):
203 """divmod(other, self): The pair (self // other, self % other).
205 Sometimes this can be computed faster than the pair of
206 operations.
208 return (other // self, other % self)
210 @abstractmethod
211 def __floordiv__(self, other):
212 """self // other: The floor() of self/other."""
213 raise NotImplementedError
215 @abstractmethod
216 def __rfloordiv__(self, other):
217 """other // self: The floor() of other/self."""
218 raise NotImplementedError
220 @abstractmethod
221 def __mod__(self, other):
222 """self % other"""
223 raise NotImplementedError
225 @abstractmethod
226 def __rmod__(self, other):
227 """other % self"""
228 raise NotImplementedError
230 @abstractmethod
231 def __lt__(self, other):
232 """self < other
234 < on Reals defines a total ordering, except perhaps for NaN."""
235 raise NotImplementedError
237 @abstractmethod
238 def __le__(self, other):
239 """self <= other"""
240 raise NotImplementedError
242 # Concrete implementations of Complex abstract methods.
243 def __complex__(self):
244 """complex(self) == complex(float(self), 0)"""
245 return complex(float(self))
247 @property
248 def real(self):
249 """Real numbers are their real component."""
250 return +self
252 @property
253 def imag(self):
254 """Real numbers have no imaginary component."""
255 return 0
257 def conjugate(self):
258 """Conjugate is a no-op for Reals."""
259 return +self
261 Real.register(float)
264 class Rational(Real):
265 """.numerator and .denominator should be in lowest terms."""
267 @abstractproperty
268 def numerator(self):
269 raise NotImplementedError
271 @abstractproperty
272 def denominator(self):
273 raise NotImplementedError
275 # Concrete implementation of Real's conversion to float.
276 def __float__(self):
277 """float(self) = self.numerator / self.denominator
279 It's important that this conversion use the integer's "true"
280 division rather than casting one side to float before dividing
281 so that ratios of huge integers convert without overflowing.
284 return self.numerator / self.denominator
287 class Integral(Rational):
288 """Integral adds a conversion to int and the bit-string operations."""
290 @abstractmethod
291 def __int__(self):
292 """int(self)"""
293 raise NotImplementedError
295 def __index__(self):
296 """index(self)"""
297 return int(self)
299 @abstractmethod
300 def __pow__(self, exponent, modulus=None):
301 """self ** exponent % modulus, but maybe faster.
303 Accept the modulus argument if you want to support the
304 3-argument version of pow(). Raise a TypeError if exponent < 0
305 or any argument isn't Integral. Otherwise, just implement the
306 2-argument version described in Complex.
308 raise NotImplementedError
310 @abstractmethod
311 def __lshift__(self, other):
312 """self << other"""
313 raise NotImplementedError
315 @abstractmethod
316 def __rlshift__(self, other):
317 """other << self"""
318 raise NotImplementedError
320 @abstractmethod
321 def __rshift__(self, other):
322 """self >> other"""
323 raise NotImplementedError
325 @abstractmethod
326 def __rrshift__(self, other):
327 """other >> self"""
328 raise NotImplementedError
330 @abstractmethod
331 def __and__(self, other):
332 """self & other"""
333 raise NotImplementedError
335 @abstractmethod
336 def __rand__(self, other):
337 """other & self"""
338 raise NotImplementedError
340 @abstractmethod
341 def __xor__(self, other):
342 """self ^ other"""
343 raise NotImplementedError
345 @abstractmethod
346 def __rxor__(self, other):
347 """other ^ self"""
348 raise NotImplementedError
350 @abstractmethod
351 def __or__(self, other):
352 """self | other"""
353 raise NotImplementedError
355 @abstractmethod
356 def __ror__(self, other):
357 """other | self"""
358 raise NotImplementedError
360 @abstractmethod
361 def __invert__(self):
362 """~self"""
363 raise NotImplementedError
365 # Concrete implementations of Rational and Real abstract methods.
366 def __float__(self):
367 """float(self) == float(int(self))"""
368 return float(int(self))
370 @property
371 def numerator(self):
372 """Integers are their own numerators."""
373 return +self
375 @property
376 def denominator(self):
377 """Integers have a denominator of 1."""
378 return 1
380 Integral.register(int)