blob: 15711ed28728b48bd78667542988bd635a990e10 [file] [log] [blame]
Jeffrey Yasskind7b00332008-01-15 07:46:24 +00001# Originally contributed by Sjoerd Mullender.
2# Significantly modified by Jeffrey Yasskin <jyasskin at gmail.com>.
3
4"""Rational, infinite-precision, real numbers."""
5
6from __future__ import division
7import math
8import numbers
9import operator
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +000010import re
Jeffrey Yasskind7b00332008-01-15 07:46:24 +000011
Raymond Hettingercf98f032008-05-08 04:36:12 +000012__all__ = ['Fraction', 'gcd']
Jeffrey Yasskind7b00332008-01-15 07:46:24 +000013
Mark Dickinsond058cd22008-02-10 21:29:51 +000014Rational = numbers.Rational
Jeffrey Yasskind7b00332008-01-15 07:46:24 +000015
16
Jeffrey Yasskin3e1a3732008-01-27 05:40:35 +000017def gcd(a, b):
18 """Calculate the Greatest Common Divisor of a and b.
Jeffrey Yasskind7b00332008-01-15 07:46:24 +000019
20 Unless b==0, the result will have the same sign as b (so that when
21 b is divided by it, the result comes out positive).
22 """
23 while b:
24 a, b = b, a%b
25 return a
26
27
Mark Dickinson1dabdb22008-02-02 17:16:13 +000028_RATIONAL_FORMAT = re.compile(r"""
29 \A\s* # optional whitespace at the start, then
30 (?P<sign>[-+]?) # an optional sign, then
31 (?=\d|\.\d) # lookahead for digit or .digit
32 (?P<num>\d*) # numerator (possibly empty)
Mark Dickinson8100bd82009-04-22 18:15:25 +000033 (?: # followed by
34 (?:/(?P<denom>\d+))? # an optional denominator
Mark Dickinson1dabdb22008-02-02 17:16:13 +000035 | # or
Mark Dickinson8100bd82009-04-22 18:15:25 +000036 (?:\.(?P<decimal>\d*))? # an optional fractional part
37 (?:E(?P<exp>[-+]?\d+))? # and optional exponent
38 )
Mark Dickinson1dabdb22008-02-02 17:16:13 +000039 \s*\Z # and optional whitespace to finish
Mark Dickinson8100bd82009-04-22 18:15:25 +000040""", re.VERBOSE | re.IGNORECASE)
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +000041
42
Mark Dickinsond058cd22008-02-10 21:29:51 +000043class Fraction(Rational):
Jeffrey Yasskind7b00332008-01-15 07:46:24 +000044 """This class implements rational numbers.
45
Mark Dickinsond058cd22008-02-10 21:29:51 +000046 Fraction(8, 6) will produce a rational number equivalent to
Jeffrey Yasskind7b00332008-01-15 07:46:24 +000047 4/3. Both arguments must be Integral. The numerator defaults to 0
Mark Dickinsond058cd22008-02-10 21:29:51 +000048 and the denominator defaults to 1 so that Fraction(3) == 3 and
49 Fraction() == 0.
Jeffrey Yasskind7b00332008-01-15 07:46:24 +000050
Mark Dickinsond058cd22008-02-10 21:29:51 +000051 Fractions can also be constructed from strings of the form
Jeffrey Yasskin3e1a3732008-01-27 05:40:35 +000052 '[-+]?[0-9]+((/|.)[0-9]+)?', optionally surrounded by spaces.
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +000053
Jeffrey Yasskind7b00332008-01-15 07:46:24 +000054 """
55
Jeffrey Yasskindc2964b2008-02-01 07:05:46 +000056 __slots__ = ('_numerator', '_denominator')
Jeffrey Yasskind7b00332008-01-15 07:46:24 +000057
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +000058 # We're immutable, so use __new__ not __init__
Mark Dickinson4af8e742009-04-24 13:56:07 +000059 def __new__(cls, numerator=0, denominator=None):
Mark Dickinsond058cd22008-02-10 21:29:51 +000060 """Constructs a Fraction.
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +000061
Mark Dickinsond058cd22008-02-10 21:29:51 +000062 Takes a string like '3/2' or '1.5', another Fraction, or a
Jeffrey Yasskin3e1a3732008-01-27 05:40:35 +000063 numerator/denominator pair.
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +000064
65 """
Mark Dickinsond058cd22008-02-10 21:29:51 +000066 self = super(Fraction, cls).__new__(cls)
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +000067
Mark Dickinson4af8e742009-04-24 13:56:07 +000068 if denominator is None:
69 if isinstance(numerator, Rational):
70 self._numerator = numerator.numerator
71 self._denominator = numerator.denominator
72 return self
73
74 elif isinstance(numerator, basestring):
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +000075 # Handle construction from strings.
Mark Dickinson8100bd82009-04-22 18:15:25 +000076 m = _RATIONAL_FORMAT.match(numerator)
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +000077 if m is None:
Mark Dickinson8100bd82009-04-22 18:15:25 +000078 raise ValueError('Invalid literal for Fraction: %r' %
79 numerator)
80 numerator = int(m.group('num') or '0')
81 denom = m.group('denom')
82 if denom:
83 denominator = int(denom)
Jeffrey Yasskin3e1a3732008-01-27 05:40:35 +000084 else:
Mark Dickinson8100bd82009-04-22 18:15:25 +000085 denominator = 1
86 decimal = m.group('decimal')
87 if decimal:
88 scale = 10**len(decimal)
89 numerator = numerator * scale + int(decimal)
90 denominator *= scale
91 exp = m.group('exp')
92 if exp:
93 exp = int(exp)
94 if exp >= 0:
95 numerator *= 10**exp
96 else:
97 denominator *= 10**-exp
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +000098 if m.group('sign') == '-':
99 numerator = -numerator
100
Mark Dickinson4af8e742009-04-24 13:56:07 +0000101 else:
102 raise TypeError("argument should be a string "
103 "or a Rational instance")
104
105 elif (isinstance(numerator, Rational) and
106 isinstance(denominator, Rational)):
107 numerator, denominator = (
108 numerator.numerator * denominator.denominator,
109 denominator.numerator * numerator.denominator
110 )
111 else:
112 raise TypeError("both arguments should be "
113 "Rational instances")
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000114
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000115 if denominator == 0:
Mark Dickinsond058cd22008-02-10 21:29:51 +0000116 raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
Jeffrey Yasskin3e1a3732008-01-27 05:40:35 +0000117 g = gcd(numerator, denominator)
Jeffrey Yasskin1c214d62008-02-14 06:12:24 +0000118 self._numerator = numerator // g
119 self._denominator = denominator // g
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +0000120 return self
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000121
Mark Dickinson0aa52a12008-02-12 21:40:53 +0000122 @classmethod
123 def from_float(cls, f):
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +0000124 """Converts a finite float to a rational number, exactly.
125
Mark Dickinsond058cd22008-02-10 21:29:51 +0000126 Beware that Fraction.from_float(0.3) != Fraction(3, 10).
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +0000127
128 """
Raymond Hettingerb01713e2008-07-10 14:34:57 +0000129 if isinstance(f, numbers.Integral):
Georg Brandlfe427892009-01-03 22:03:11 +0000130 return cls(f)
Raymond Hettingerb01713e2008-07-10 14:34:57 +0000131 elif not isinstance(f, float):
Mark Dickinson0aa52a12008-02-12 21:40:53 +0000132 raise TypeError("%s.from_float() only takes floats, not %r (%s)" %
133 (cls.__name__, f, type(f).__name__))
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000134 if math.isnan(f) or math.isinf(f):
Mark Dickinson0aa52a12008-02-12 21:40:53 +0000135 raise TypeError("Cannot convert %r to %s." % (f, cls.__name__))
136 return cls(*f.as_integer_ratio())
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000137
Mark Dickinson0aa52a12008-02-12 21:40:53 +0000138 @classmethod
139 def from_decimal(cls, dec):
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +0000140 """Converts a finite Decimal instance to a rational number, exactly."""
141 from decimal import Decimal
Raymond Hettingerb01713e2008-07-10 14:34:57 +0000142 if isinstance(dec, numbers.Integral):
143 dec = Decimal(int(dec))
144 elif not isinstance(dec, Decimal):
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +0000145 raise TypeError(
Mark Dickinson0aa52a12008-02-12 21:40:53 +0000146 "%s.from_decimal() only takes Decimals, not %r (%s)" %
147 (cls.__name__, dec, type(dec).__name__))
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +0000148 if not dec.is_finite():
149 # Catches infinities and nans.
Mark Dickinson0aa52a12008-02-12 21:40:53 +0000150 raise TypeError("Cannot convert %s to %s." % (dec, cls.__name__))
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +0000151 sign, digits, exp = dec.as_tuple()
152 digits = int(''.join(map(str, digits)))
153 if sign:
154 digits = -digits
155 if exp >= 0:
Mark Dickinson0aa52a12008-02-12 21:40:53 +0000156 return cls(digits * 10 ** exp)
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +0000157 else:
Mark Dickinson0aa52a12008-02-12 21:40:53 +0000158 return cls(digits, 10 ** -exp)
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +0000159
Mark Dickinsone1b82472008-02-12 21:31:59 +0000160 def limit_denominator(self, max_denominator=1000000):
161 """Closest Fraction to self with denominator at most max_denominator.
Raymond Hettingercf109262008-01-24 00:54:21 +0000162
Mark Dickinsone1b82472008-02-12 21:31:59 +0000163 >>> Fraction('3.141592653589793').limit_denominator(10)
164 Fraction(22, 7)
165 >>> Fraction('3.141592653589793').limit_denominator(100)
166 Fraction(311, 99)
167 >>> Fraction(1234, 5678).limit_denominator(10000)
168 Fraction(1234, 5678)
Raymond Hettingercf109262008-01-24 00:54:21 +0000169
Mark Dickinsone1b82472008-02-12 21:31:59 +0000170 """
171 # Algorithm notes: For any real number x, define a *best upper
172 # approximation* to x to be a rational number p/q such that:
173 #
174 # (1) p/q >= x, and
175 # (2) if p/q > r/s >= x then s > q, for any rational r/s.
176 #
177 # Define *best lower approximation* similarly. Then it can be
178 # proved that a rational number is a best upper or lower
179 # approximation to x if, and only if, it is a convergent or
180 # semiconvergent of the (unique shortest) continued fraction
181 # associated to x.
182 #
183 # To find a best rational approximation with denominator <= M,
184 # we find the best upper and lower approximations with
185 # denominator <= M and take whichever of these is closer to x.
186 # In the event of a tie, the bound with smaller denominator is
187 # chosen. If both denominators are equal (which can happen
188 # only when max_denominator == 1 and self is midway between
189 # two integers) the lower bound---i.e., the floor of self, is
190 # taken.
191
192 if max_denominator < 1:
193 raise ValueError("max_denominator should be at least 1")
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000194 if self._denominator <= max_denominator:
Mark Dickinsone1b82472008-02-12 21:31:59 +0000195 return Fraction(self)
196
197 p0, q0, p1, q1 = 0, 1, 1, 0
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000198 n, d = self._numerator, self._denominator
Mark Dickinsone1b82472008-02-12 21:31:59 +0000199 while True:
200 a = n//d
201 q2 = q0+a*q1
202 if q2 > max_denominator:
Raymond Hettingercf109262008-01-24 00:54:21 +0000203 break
Mark Dickinsone1b82472008-02-12 21:31:59 +0000204 p0, q0, p1, q1 = p1, q1, p0+a*p1, q2
205 n, d = d, n-a*d
206
207 k = (max_denominator-q0)//q1
208 bound1 = Fraction(p0+k*p1, q0+k*q1)
209 bound2 = Fraction(p1, q1)
210 if abs(bound2 - self) <= abs(bound1-self):
211 return bound2
212 else:
213 return bound1
Raymond Hettingercf109262008-01-24 00:54:21 +0000214
Jeffrey Yasskindc2964b2008-02-01 07:05:46 +0000215 @property
216 def numerator(a):
217 return a._numerator
218
219 @property
220 def denominator(a):
221 return a._denominator
222
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000223 def __repr__(self):
224 """repr(self)"""
Mark Dickinson3af386a2008-06-27 10:11:52 +0000225 return ('Fraction(%s, %s)' % (self._numerator, self._denominator))
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000226
227 def __str__(self):
228 """str(self)"""
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000229 if self._denominator == 1:
230 return str(self._numerator)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000231 else:
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000232 return '%s/%s' % (self._numerator, self._denominator)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000233
234 def _operator_fallbacks(monomorphic_operator, fallback_operator):
235 """Generates forward and reverse operators given a purely-rational
236 operator and a function from the operator module.
237
238 Use this like:
239 __op__, __rop__ = _operator_fallbacks(just_rational_op, operator.op)
240
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000241 In general, we want to implement the arithmetic operations so
242 that mixed-mode operations either call an implementation whose
243 author knew about the types of both arguments, or convert both
244 to the nearest built in type and do the operation there. In
Mark Dickinsond058cd22008-02-10 21:29:51 +0000245 Fraction, that means that we define __add__ and __radd__ as:
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000246
247 def __add__(self, other):
Raymond Hettinger2df20a32008-01-31 22:07:16 +0000248 # Both types have numerators/denominator attributes,
249 # so do the operation directly
Mark Dickinsond058cd22008-02-10 21:29:51 +0000250 if isinstance(other, (int, long, Fraction)):
251 return Fraction(self.numerator * other.denominator +
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000252 other.numerator * self.denominator,
253 self.denominator * other.denominator)
Raymond Hettinger2df20a32008-01-31 22:07:16 +0000254 # float and complex don't have those operations, but we
255 # know about those types, so special case them.
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000256 elif isinstance(other, float):
257 return float(self) + other
258 elif isinstance(other, complex):
259 return complex(self) + other
Raymond Hettinger2df20a32008-01-31 22:07:16 +0000260 # Let the other type take over.
261 return NotImplemented
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000262
263 def __radd__(self, other):
264 # radd handles more types than add because there's
265 # nothing left to fall back to.
Mark Dickinsond058cd22008-02-10 21:29:51 +0000266 if isinstance(other, Rational):
267 return Fraction(self.numerator * other.denominator +
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000268 other.numerator * self.denominator,
269 self.denominator * other.denominator)
270 elif isinstance(other, Real):
271 return float(other) + float(self)
272 elif isinstance(other, Complex):
273 return complex(other) + complex(self)
Raymond Hettinger2df20a32008-01-31 22:07:16 +0000274 return NotImplemented
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000275
276
277 There are 5 different cases for a mixed-type addition on
Mark Dickinsond058cd22008-02-10 21:29:51 +0000278 Fraction. I'll refer to all of the above code that doesn't
279 refer to Fraction, float, or complex as "boilerplate". 'r'
280 will be an instance of Fraction, which is a subtype of
281 Rational (r : Fraction <: Rational), and b : B <:
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000282 Complex. The first three involve 'r + b':
283
Mark Dickinsond058cd22008-02-10 21:29:51 +0000284 1. If B <: Fraction, int, float, or complex, we handle
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000285 that specially, and all is well.
Mark Dickinsond058cd22008-02-10 21:29:51 +0000286 2. If Fraction falls back to the boilerplate code, and it
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000287 were to return a value from __add__, we'd miss the
288 possibility that B defines a more intelligent __radd__,
289 so the boilerplate should return NotImplemented from
Mark Dickinsond058cd22008-02-10 21:29:51 +0000290 __add__. In particular, we don't handle Rational
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000291 here, even though we could get an exact answer, in case
292 the other type wants to do something special.
Mark Dickinsond058cd22008-02-10 21:29:51 +0000293 3. If B <: Fraction, Python tries B.__radd__ before
294 Fraction.__add__. This is ok, because it was
295 implemented with knowledge of Fraction, so it can
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000296 handle those instances before delegating to Real or
297 Complex.
298
299 The next two situations describe 'b + r'. We assume that b
Mark Dickinsond058cd22008-02-10 21:29:51 +0000300 didn't know about Fraction in its implementation, and that it
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000301 uses similar boilerplate code:
302
Mark Dickinsond058cd22008-02-10 21:29:51 +0000303 4. If B <: Rational, then __radd_ converts both to the
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000304 builtin rational type (hey look, that's us) and
305 proceeds.
306 5. Otherwise, __radd__ tries to find the nearest common
307 base ABC, and fall back to its builtin type. Since this
308 class doesn't subclass a concrete type, there's no
309 implementation to fall back to, so we need to try as
310 hard as possible to return an actual value, or the user
311 will get a TypeError.
312
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000313 """
314 def forward(a, b):
Mark Dickinsond058cd22008-02-10 21:29:51 +0000315 if isinstance(b, (int, long, Fraction)):
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000316 return monomorphic_operator(a, b)
317 elif isinstance(b, float):
318 return fallback_operator(float(a), b)
319 elif isinstance(b, complex):
320 return fallback_operator(complex(a), b)
321 else:
322 return NotImplemented
323 forward.__name__ = '__' + fallback_operator.__name__ + '__'
324 forward.__doc__ = monomorphic_operator.__doc__
325
326 def reverse(b, a):
Mark Dickinsond058cd22008-02-10 21:29:51 +0000327 if isinstance(a, Rational):
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000328 # Includes ints.
329 return monomorphic_operator(a, b)
330 elif isinstance(a, numbers.Real):
331 return fallback_operator(float(a), float(b))
332 elif isinstance(a, numbers.Complex):
333 return fallback_operator(complex(a), complex(b))
334 else:
335 return NotImplemented
336 reverse.__name__ = '__r' + fallback_operator.__name__ + '__'
337 reverse.__doc__ = monomorphic_operator.__doc__
338
339 return forward, reverse
340
341 def _add(a, b):
342 """a + b"""
Mark Dickinsond058cd22008-02-10 21:29:51 +0000343 return Fraction(a.numerator * b.denominator +
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000344 b.numerator * a.denominator,
345 a.denominator * b.denominator)
346
347 __add__, __radd__ = _operator_fallbacks(_add, operator.add)
348
349 def _sub(a, b):
350 """a - b"""
Mark Dickinsond058cd22008-02-10 21:29:51 +0000351 return Fraction(a.numerator * b.denominator -
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000352 b.numerator * a.denominator,
353 a.denominator * b.denominator)
354
355 __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub)
356
357 def _mul(a, b):
358 """a * b"""
Mark Dickinsond058cd22008-02-10 21:29:51 +0000359 return Fraction(a.numerator * b.numerator, a.denominator * b.denominator)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000360
361 __mul__, __rmul__ = _operator_fallbacks(_mul, operator.mul)
362
363 def _div(a, b):
364 """a / b"""
Mark Dickinsond058cd22008-02-10 21:29:51 +0000365 return Fraction(a.numerator * b.denominator,
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000366 a.denominator * b.numerator)
367
368 __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv)
369 __div__, __rdiv__ = _operator_fallbacks(_div, operator.div)
370
Raymond Hettinger909e3342008-01-24 23:50:26 +0000371 def __floordiv__(a, b):
372 """a // b"""
373 # Will be math.floor(a / b) in 3.0.
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000374 div = a / b
Mark Dickinsond058cd22008-02-10 21:29:51 +0000375 if isinstance(div, Rational):
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000376 # trunc(math.floor(div)) doesn't work if the rational is
377 # more precise than a float because the intermediate
378 # rounding may cross an integer boundary.
379 return div.numerator // div.denominator
380 else:
381 return math.floor(div)
382
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000383 def __rfloordiv__(b, a):
384 """a // b"""
385 # Will be math.floor(a / b) in 3.0.
Raymond Hettinger909e3342008-01-24 23:50:26 +0000386 div = a / b
Mark Dickinsond058cd22008-02-10 21:29:51 +0000387 if isinstance(div, Rational):
Raymond Hettinger909e3342008-01-24 23:50:26 +0000388 # trunc(math.floor(div)) doesn't work if the rational is
389 # more precise than a float because the intermediate
390 # rounding may cross an integer boundary.
391 return div.numerator // div.denominator
392 else:
393 return math.floor(div)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000394
395 def __mod__(a, b):
396 """a % b"""
Raymond Hettinger909e3342008-01-24 23:50:26 +0000397 div = a // b
398 return a - b * div
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000399
400 def __rmod__(b, a):
401 """a % b"""
Raymond Hettinger909e3342008-01-24 23:50:26 +0000402 div = a // b
403 return a - b * div
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000404
405 def __pow__(a, b):
406 """a ** b
407
408 If b is not an integer, the result will be a float or complex
409 since roots are generally irrational. If b is an integer, the
410 result will be rational.
411
412 """
Mark Dickinsond058cd22008-02-10 21:29:51 +0000413 if isinstance(b, Rational):
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000414 if b.denominator == 1:
415 power = b.numerator
416 if power >= 0:
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000417 return Fraction(a._numerator ** power,
418 a._denominator ** power)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000419 else:
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000420 return Fraction(a._denominator ** -power,
421 a._numerator ** -power)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000422 else:
423 # A fractional power will generally produce an
424 # irrational number.
425 return float(a) ** float(b)
426 else:
427 return float(a) ** b
428
429 def __rpow__(b, a):
430 """a ** b"""
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000431 if b._denominator == 1 and b._numerator >= 0:
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000432 # If a is an int, keep it that way if possible.
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000433 return a ** b._numerator
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000434
Mark Dickinsond058cd22008-02-10 21:29:51 +0000435 if isinstance(a, Rational):
436 return Fraction(a.numerator, a.denominator) ** b
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000437
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000438 if b._denominator == 1:
439 return a ** b._numerator
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000440
441 return a ** float(b)
442
443 def __pos__(a):
Mark Dickinsond058cd22008-02-10 21:29:51 +0000444 """+a: Coerces a subclass instance to Fraction"""
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000445 return Fraction(a._numerator, a._denominator)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000446
447 def __neg__(a):
448 """-a"""
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000449 return Fraction(-a._numerator, a._denominator)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000450
451 def __abs__(a):
452 """abs(a)"""
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000453 return Fraction(abs(a._numerator), a._denominator)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000454
455 def __trunc__(a):
456 """trunc(a)"""
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000457 if a._numerator < 0:
458 return -(-a._numerator // a._denominator)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000459 else:
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000460 return a._numerator // a._denominator
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000461
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000462 def __hash__(self):
463 """hash(self)
464
465 Tricky because values that are exactly representable as a
466 float must have the same hash as that float.
467
468 """
Raymond Hettinger921cb5d2008-01-25 00:33:45 +0000469 # XXX since this method is expensive, consider caching the result
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000470 if self._denominator == 1:
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000471 # Get integers right.
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000472 return hash(self._numerator)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000473 # Expensive check, but definitely correct.
474 if self == float(self):
475 return hash(float(self))
476 else:
477 # Use tuple's hash to avoid a high collision rate on
478 # simple fractions.
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000479 return hash((self._numerator, self._denominator))
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000480
481 def __eq__(a, b):
482 """a == b"""
Mark Dickinsond058cd22008-02-10 21:29:51 +0000483 if isinstance(b, Rational):
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000484 return (a._numerator == b.numerator and
485 a._denominator == b.denominator)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000486 if isinstance(b, numbers.Complex) and b.imag == 0:
487 b = b.real
488 if isinstance(b, float):
489 return a == a.from_float(b)
490 else:
491 # XXX: If b.__eq__ is implemented like this method, it may
492 # give the wrong answer after float(a) changes a's
493 # value. Better ways of doing this are welcome.
494 return float(a) == b
495
496 def _subtractAndCompareToZero(a, b, op):
497 """Helper function for comparison operators.
498
499 Subtracts b from a, exactly if possible, and compares the
500 result with 0 using op, in such a way that the comparison
501 won't recurse. If the difference raises a TypeError, returns
502 NotImplemented instead.
503
504 """
505 if isinstance(b, numbers.Complex) and b.imag == 0:
506 b = b.real
507 if isinstance(b, float):
508 b = a.from_float(b)
509 try:
Mark Dickinsond058cd22008-02-10 21:29:51 +0000510 # XXX: If b <: Real but not <: Rational, this is likely
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000511 # to fall back to a float. If the actual values differ by
512 # less than MIN_FLOAT, this could falsely call them equal,
513 # which would make <= inconsistent with ==. Better ways of
514 # doing this are welcome.
515 diff = a - b
516 except TypeError:
517 return NotImplemented
Mark Dickinsond058cd22008-02-10 21:29:51 +0000518 if isinstance(diff, Rational):
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000519 return op(diff.numerator, 0)
520 return op(diff, 0)
521
522 def __lt__(a, b):
523 """a < b"""
524 return a._subtractAndCompareToZero(b, operator.lt)
525
526 def __gt__(a, b):
527 """a > b"""
528 return a._subtractAndCompareToZero(b, operator.gt)
529
530 def __le__(a, b):
531 """a <= b"""
532 return a._subtractAndCompareToZero(b, operator.le)
533
534 def __ge__(a, b):
535 """a >= b"""
536 return a._subtractAndCompareToZero(b, operator.ge)
537
538 def __nonzero__(a):
539 """a != 0"""
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000540 return a._numerator != 0
Raymond Hettingera6216742008-01-25 00:21:54 +0000541
542 # support for pickling, copy, and deepcopy
543
544 def __reduce__(self):
545 return (self.__class__, (str(self),))
546
547 def __copy__(self):
Mark Dickinsond058cd22008-02-10 21:29:51 +0000548 if type(self) == Fraction:
Raymond Hettingera6216742008-01-25 00:21:54 +0000549 return self # I'm immutable; therefore I am my own clone
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000550 return self.__class__(self._numerator, self._denominator)
Raymond Hettingera6216742008-01-25 00:21:54 +0000551
552 def __deepcopy__(self, memo):
Mark Dickinsond058cd22008-02-10 21:29:51 +0000553 if type(self) == Fraction:
Raymond Hettingera6216742008-01-25 00:21:54 +0000554 return self # My components are also immutable
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000555 return self.__class__(self._numerator, self._denominator)