blob: 7db6b5b1f87d425075ed108f8dcacbee2d92d8c8 [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__
59 def __new__(cls, numerator=0, denominator=1):
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
Jeffrey Yasskin1c214d62008-02-14 06:12:24 +000068 if type(numerator) not in (int, long) and denominator == 1:
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +000069 if isinstance(numerator, basestring):
70 # Handle construction from strings.
Mark Dickinson8100bd82009-04-22 18:15:25 +000071 m = _RATIONAL_FORMAT.match(numerator)
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +000072 if m is None:
Mark Dickinson8100bd82009-04-22 18:15:25 +000073 raise ValueError('Invalid literal for Fraction: %r' %
74 numerator)
75 numerator = int(m.group('num') or '0')
76 denom = m.group('denom')
77 if denom:
78 denominator = int(denom)
Jeffrey Yasskin3e1a3732008-01-27 05:40:35 +000079 else:
Mark Dickinson8100bd82009-04-22 18:15:25 +000080 denominator = 1
81 decimal = m.group('decimal')
82 if decimal:
83 scale = 10**len(decimal)
84 numerator = numerator * scale + int(decimal)
85 denominator *= scale
86 exp = m.group('exp')
87 if exp:
88 exp = int(exp)
89 if exp >= 0:
90 numerator *= 10**exp
91 else:
92 denominator *= 10**-exp
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +000093 if m.group('sign') == '-':
94 numerator = -numerator
95
Jeffrey Yasskin1c214d62008-02-14 06:12:24 +000096 elif isinstance(numerator, Rational):
97 # Handle copies from other rationals. Integrals get
98 # caught here too, but it doesn't matter because
99 # denominator is already 1.
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +0000100 other_rational = numerator
101 numerator = other_rational.numerator
102 denominator = other_rational.denominator
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000103
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000104 if denominator == 0:
Mark Dickinsond058cd22008-02-10 21:29:51 +0000105 raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
Raymond Hettinger548db582008-07-10 10:28:41 +0000106 numerator = operator.index(numerator)
107 denominator = operator.index(denominator)
Jeffrey Yasskin3e1a3732008-01-27 05:40:35 +0000108 g = gcd(numerator, denominator)
Jeffrey Yasskin1c214d62008-02-14 06:12:24 +0000109 self._numerator = numerator // g
110 self._denominator = denominator // g
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +0000111 return self
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000112
Mark Dickinson0aa52a12008-02-12 21:40:53 +0000113 @classmethod
114 def from_float(cls, f):
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +0000115 """Converts a finite float to a rational number, exactly.
116
Mark Dickinsond058cd22008-02-10 21:29:51 +0000117 Beware that Fraction.from_float(0.3) != Fraction(3, 10).
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +0000118
119 """
Raymond Hettingerb01713e2008-07-10 14:34:57 +0000120 if isinstance(f, numbers.Integral):
Georg Brandlfe427892009-01-03 22:03:11 +0000121 return cls(f)
Raymond Hettingerb01713e2008-07-10 14:34:57 +0000122 elif not isinstance(f, float):
Mark Dickinson0aa52a12008-02-12 21:40:53 +0000123 raise TypeError("%s.from_float() only takes floats, not %r (%s)" %
124 (cls.__name__, f, type(f).__name__))
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000125 if math.isnan(f) or math.isinf(f):
Mark Dickinson0aa52a12008-02-12 21:40:53 +0000126 raise TypeError("Cannot convert %r to %s." % (f, cls.__name__))
127 return cls(*f.as_integer_ratio())
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000128
Mark Dickinson0aa52a12008-02-12 21:40:53 +0000129 @classmethod
130 def from_decimal(cls, dec):
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +0000131 """Converts a finite Decimal instance to a rational number, exactly."""
132 from decimal import Decimal
Raymond Hettingerb01713e2008-07-10 14:34:57 +0000133 if isinstance(dec, numbers.Integral):
134 dec = Decimal(int(dec))
135 elif not isinstance(dec, Decimal):
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +0000136 raise TypeError(
Mark Dickinson0aa52a12008-02-12 21:40:53 +0000137 "%s.from_decimal() only takes Decimals, not %r (%s)" %
138 (cls.__name__, dec, type(dec).__name__))
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +0000139 if not dec.is_finite():
140 # Catches infinities and nans.
Mark Dickinson0aa52a12008-02-12 21:40:53 +0000141 raise TypeError("Cannot convert %s to %s." % (dec, cls.__name__))
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +0000142 sign, digits, exp = dec.as_tuple()
143 digits = int(''.join(map(str, digits)))
144 if sign:
145 digits = -digits
146 if exp >= 0:
Mark Dickinson0aa52a12008-02-12 21:40:53 +0000147 return cls(digits * 10 ** exp)
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +0000148 else:
Mark Dickinson0aa52a12008-02-12 21:40:53 +0000149 return cls(digits, 10 ** -exp)
Jeffrey Yasskin45169fb2008-01-19 09:56:06 +0000150
Mark Dickinsone1b82472008-02-12 21:31:59 +0000151 def limit_denominator(self, max_denominator=1000000):
152 """Closest Fraction to self with denominator at most max_denominator.
Raymond Hettingercf109262008-01-24 00:54:21 +0000153
Mark Dickinsone1b82472008-02-12 21:31:59 +0000154 >>> Fraction('3.141592653589793').limit_denominator(10)
155 Fraction(22, 7)
156 >>> Fraction('3.141592653589793').limit_denominator(100)
157 Fraction(311, 99)
158 >>> Fraction(1234, 5678).limit_denominator(10000)
159 Fraction(1234, 5678)
Raymond Hettingercf109262008-01-24 00:54:21 +0000160
Mark Dickinsone1b82472008-02-12 21:31:59 +0000161 """
162 # Algorithm notes: For any real number x, define a *best upper
163 # approximation* to x to be a rational number p/q such that:
164 #
165 # (1) p/q >= x, and
166 # (2) if p/q > r/s >= x then s > q, for any rational r/s.
167 #
168 # Define *best lower approximation* similarly. Then it can be
169 # proved that a rational number is a best upper or lower
170 # approximation to x if, and only if, it is a convergent or
171 # semiconvergent of the (unique shortest) continued fraction
172 # associated to x.
173 #
174 # To find a best rational approximation with denominator <= M,
175 # we find the best upper and lower approximations with
176 # denominator <= M and take whichever of these is closer to x.
177 # In the event of a tie, the bound with smaller denominator is
178 # chosen. If both denominators are equal (which can happen
179 # only when max_denominator == 1 and self is midway between
180 # two integers) the lower bound---i.e., the floor of self, is
181 # taken.
182
183 if max_denominator < 1:
184 raise ValueError("max_denominator should be at least 1")
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000185 if self._denominator <= max_denominator:
Mark Dickinsone1b82472008-02-12 21:31:59 +0000186 return Fraction(self)
187
188 p0, q0, p1, q1 = 0, 1, 1, 0
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000189 n, d = self._numerator, self._denominator
Mark Dickinsone1b82472008-02-12 21:31:59 +0000190 while True:
191 a = n//d
192 q2 = q0+a*q1
193 if q2 > max_denominator:
Raymond Hettingercf109262008-01-24 00:54:21 +0000194 break
Mark Dickinsone1b82472008-02-12 21:31:59 +0000195 p0, q0, p1, q1 = p1, q1, p0+a*p1, q2
196 n, d = d, n-a*d
197
198 k = (max_denominator-q0)//q1
199 bound1 = Fraction(p0+k*p1, q0+k*q1)
200 bound2 = Fraction(p1, q1)
201 if abs(bound2 - self) <= abs(bound1-self):
202 return bound2
203 else:
204 return bound1
Raymond Hettingercf109262008-01-24 00:54:21 +0000205
Jeffrey Yasskindc2964b2008-02-01 07:05:46 +0000206 @property
207 def numerator(a):
208 return a._numerator
209
210 @property
211 def denominator(a):
212 return a._denominator
213
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000214 def __repr__(self):
215 """repr(self)"""
Mark Dickinson3af386a2008-06-27 10:11:52 +0000216 return ('Fraction(%s, %s)' % (self._numerator, self._denominator))
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000217
218 def __str__(self):
219 """str(self)"""
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000220 if self._denominator == 1:
221 return str(self._numerator)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000222 else:
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000223 return '%s/%s' % (self._numerator, self._denominator)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000224
225 def _operator_fallbacks(monomorphic_operator, fallback_operator):
226 """Generates forward and reverse operators given a purely-rational
227 operator and a function from the operator module.
228
229 Use this like:
230 __op__, __rop__ = _operator_fallbacks(just_rational_op, operator.op)
231
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000232 In general, we want to implement the arithmetic operations so
233 that mixed-mode operations either call an implementation whose
234 author knew about the types of both arguments, or convert both
235 to the nearest built in type and do the operation there. In
Mark Dickinsond058cd22008-02-10 21:29:51 +0000236 Fraction, that means that we define __add__ and __radd__ as:
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000237
238 def __add__(self, other):
Raymond Hettinger2df20a32008-01-31 22:07:16 +0000239 # Both types have numerators/denominator attributes,
240 # so do the operation directly
Mark Dickinsond058cd22008-02-10 21:29:51 +0000241 if isinstance(other, (int, long, Fraction)):
242 return Fraction(self.numerator * other.denominator +
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000243 other.numerator * self.denominator,
244 self.denominator * other.denominator)
Raymond Hettinger2df20a32008-01-31 22:07:16 +0000245 # float and complex don't have those operations, but we
246 # know about those types, so special case them.
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000247 elif isinstance(other, float):
248 return float(self) + other
249 elif isinstance(other, complex):
250 return complex(self) + other
Raymond Hettinger2df20a32008-01-31 22:07:16 +0000251 # Let the other type take over.
252 return NotImplemented
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000253
254 def __radd__(self, other):
255 # radd handles more types than add because there's
256 # nothing left to fall back to.
Mark Dickinsond058cd22008-02-10 21:29:51 +0000257 if isinstance(other, Rational):
258 return Fraction(self.numerator * other.denominator +
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000259 other.numerator * self.denominator,
260 self.denominator * other.denominator)
261 elif isinstance(other, Real):
262 return float(other) + float(self)
263 elif isinstance(other, Complex):
264 return complex(other) + complex(self)
Raymond Hettinger2df20a32008-01-31 22:07:16 +0000265 return NotImplemented
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000266
267
268 There are 5 different cases for a mixed-type addition on
Mark Dickinsond058cd22008-02-10 21:29:51 +0000269 Fraction. I'll refer to all of the above code that doesn't
270 refer to Fraction, float, or complex as "boilerplate". 'r'
271 will be an instance of Fraction, which is a subtype of
272 Rational (r : Fraction <: Rational), and b : B <:
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000273 Complex. The first three involve 'r + b':
274
Mark Dickinsond058cd22008-02-10 21:29:51 +0000275 1. If B <: Fraction, int, float, or complex, we handle
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000276 that specially, and all is well.
Mark Dickinsond058cd22008-02-10 21:29:51 +0000277 2. If Fraction falls back to the boilerplate code, and it
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000278 were to return a value from __add__, we'd miss the
279 possibility that B defines a more intelligent __radd__,
280 so the boilerplate should return NotImplemented from
Mark Dickinsond058cd22008-02-10 21:29:51 +0000281 __add__. In particular, we don't handle Rational
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000282 here, even though we could get an exact answer, in case
283 the other type wants to do something special.
Mark Dickinsond058cd22008-02-10 21:29:51 +0000284 3. If B <: Fraction, Python tries B.__radd__ before
285 Fraction.__add__. This is ok, because it was
286 implemented with knowledge of Fraction, so it can
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000287 handle those instances before delegating to Real or
288 Complex.
289
290 The next two situations describe 'b + r'. We assume that b
Mark Dickinsond058cd22008-02-10 21:29:51 +0000291 didn't know about Fraction in its implementation, and that it
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000292 uses similar boilerplate code:
293
Mark Dickinsond058cd22008-02-10 21:29:51 +0000294 4. If B <: Rational, then __radd_ converts both to the
Jeffrey Yasskinb23dea62008-01-31 07:44:11 +0000295 builtin rational type (hey look, that's us) and
296 proceeds.
297 5. Otherwise, __radd__ tries to find the nearest common
298 base ABC, and fall back to its builtin type. Since this
299 class doesn't subclass a concrete type, there's no
300 implementation to fall back to, so we need to try as
301 hard as possible to return an actual value, or the user
302 will get a TypeError.
303
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000304 """
305 def forward(a, b):
Mark Dickinsond058cd22008-02-10 21:29:51 +0000306 if isinstance(b, (int, long, Fraction)):
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000307 return monomorphic_operator(a, b)
308 elif isinstance(b, float):
309 return fallback_operator(float(a), b)
310 elif isinstance(b, complex):
311 return fallback_operator(complex(a), b)
312 else:
313 return NotImplemented
314 forward.__name__ = '__' + fallback_operator.__name__ + '__'
315 forward.__doc__ = monomorphic_operator.__doc__
316
317 def reverse(b, a):
Mark Dickinsond058cd22008-02-10 21:29:51 +0000318 if isinstance(a, Rational):
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000319 # Includes ints.
320 return monomorphic_operator(a, b)
321 elif isinstance(a, numbers.Real):
322 return fallback_operator(float(a), float(b))
323 elif isinstance(a, numbers.Complex):
324 return fallback_operator(complex(a), complex(b))
325 else:
326 return NotImplemented
327 reverse.__name__ = '__r' + fallback_operator.__name__ + '__'
328 reverse.__doc__ = monomorphic_operator.__doc__
329
330 return forward, reverse
331
332 def _add(a, b):
333 """a + b"""
Mark Dickinsond058cd22008-02-10 21:29:51 +0000334 return Fraction(a.numerator * b.denominator +
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000335 b.numerator * a.denominator,
336 a.denominator * b.denominator)
337
338 __add__, __radd__ = _operator_fallbacks(_add, operator.add)
339
340 def _sub(a, b):
341 """a - b"""
Mark Dickinsond058cd22008-02-10 21:29:51 +0000342 return Fraction(a.numerator * b.denominator -
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000343 b.numerator * a.denominator,
344 a.denominator * b.denominator)
345
346 __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub)
347
348 def _mul(a, b):
349 """a * b"""
Mark Dickinsond058cd22008-02-10 21:29:51 +0000350 return Fraction(a.numerator * b.numerator, a.denominator * b.denominator)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000351
352 __mul__, __rmul__ = _operator_fallbacks(_mul, operator.mul)
353
354 def _div(a, b):
355 """a / b"""
Mark Dickinsond058cd22008-02-10 21:29:51 +0000356 return Fraction(a.numerator * b.denominator,
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000357 a.denominator * b.numerator)
358
359 __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv)
360 __div__, __rdiv__ = _operator_fallbacks(_div, operator.div)
361
Raymond Hettinger909e3342008-01-24 23:50:26 +0000362 def __floordiv__(a, b):
363 """a // b"""
364 # Will be math.floor(a / b) in 3.0.
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000365 div = a / b
Mark Dickinsond058cd22008-02-10 21:29:51 +0000366 if isinstance(div, Rational):
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000367 # trunc(math.floor(div)) doesn't work if the rational is
368 # more precise than a float because the intermediate
369 # rounding may cross an integer boundary.
370 return div.numerator // div.denominator
371 else:
372 return math.floor(div)
373
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000374 def __rfloordiv__(b, a):
375 """a // b"""
376 # Will be math.floor(a / b) in 3.0.
Raymond Hettinger909e3342008-01-24 23:50:26 +0000377 div = a / b
Mark Dickinsond058cd22008-02-10 21:29:51 +0000378 if isinstance(div, Rational):
Raymond Hettinger909e3342008-01-24 23:50:26 +0000379 # trunc(math.floor(div)) doesn't work if the rational is
380 # more precise than a float because the intermediate
381 # rounding may cross an integer boundary.
382 return div.numerator // div.denominator
383 else:
384 return math.floor(div)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000385
386 def __mod__(a, b):
387 """a % b"""
Raymond Hettinger909e3342008-01-24 23:50:26 +0000388 div = a // b
389 return a - b * div
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000390
391 def __rmod__(b, a):
392 """a % b"""
Raymond Hettinger909e3342008-01-24 23:50:26 +0000393 div = a // b
394 return a - b * div
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000395
396 def __pow__(a, b):
397 """a ** b
398
399 If b is not an integer, the result will be a float or complex
400 since roots are generally irrational. If b is an integer, the
401 result will be rational.
402
403 """
Mark Dickinsond058cd22008-02-10 21:29:51 +0000404 if isinstance(b, Rational):
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000405 if b.denominator == 1:
406 power = b.numerator
407 if power >= 0:
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000408 return Fraction(a._numerator ** power,
409 a._denominator ** power)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000410 else:
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000411 return Fraction(a._denominator ** -power,
412 a._numerator ** -power)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000413 else:
414 # A fractional power will generally produce an
415 # irrational number.
416 return float(a) ** float(b)
417 else:
418 return float(a) ** b
419
420 def __rpow__(b, a):
421 """a ** b"""
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000422 if b._denominator == 1 and b._numerator >= 0:
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000423 # If a is an int, keep it that way if possible.
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000424 return a ** b._numerator
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000425
Mark Dickinsond058cd22008-02-10 21:29:51 +0000426 if isinstance(a, Rational):
427 return Fraction(a.numerator, a.denominator) ** b
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000428
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000429 if b._denominator == 1:
430 return a ** b._numerator
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000431
432 return a ** float(b)
433
434 def __pos__(a):
Mark Dickinsond058cd22008-02-10 21:29:51 +0000435 """+a: Coerces a subclass instance to Fraction"""
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000436 return Fraction(a._numerator, a._denominator)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000437
438 def __neg__(a):
439 """-a"""
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000440 return Fraction(-a._numerator, a._denominator)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000441
442 def __abs__(a):
443 """abs(a)"""
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000444 return Fraction(abs(a._numerator), a._denominator)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000445
446 def __trunc__(a):
447 """trunc(a)"""
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000448 if a._numerator < 0:
449 return -(-a._numerator // a._denominator)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000450 else:
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000451 return a._numerator // a._denominator
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000452
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000453 def __hash__(self):
454 """hash(self)
455
456 Tricky because values that are exactly representable as a
457 float must have the same hash as that float.
458
459 """
Raymond Hettinger921cb5d2008-01-25 00:33:45 +0000460 # XXX since this method is expensive, consider caching the result
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000461 if self._denominator == 1:
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000462 # Get integers right.
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000463 return hash(self._numerator)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000464 # Expensive check, but definitely correct.
465 if self == float(self):
466 return hash(float(self))
467 else:
468 # Use tuple's hash to avoid a high collision rate on
469 # simple fractions.
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000470 return hash((self._numerator, self._denominator))
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000471
472 def __eq__(a, b):
473 """a == b"""
Mark Dickinsond058cd22008-02-10 21:29:51 +0000474 if isinstance(b, Rational):
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000475 return (a._numerator == b.numerator and
476 a._denominator == b.denominator)
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000477 if isinstance(b, numbers.Complex) and b.imag == 0:
478 b = b.real
479 if isinstance(b, float):
480 return a == a.from_float(b)
481 else:
482 # XXX: If b.__eq__ is implemented like this method, it may
483 # give the wrong answer after float(a) changes a's
484 # value. Better ways of doing this are welcome.
485 return float(a) == b
486
487 def _subtractAndCompareToZero(a, b, op):
488 """Helper function for comparison operators.
489
490 Subtracts b from a, exactly if possible, and compares the
491 result with 0 using op, in such a way that the comparison
492 won't recurse. If the difference raises a TypeError, returns
493 NotImplemented instead.
494
495 """
496 if isinstance(b, numbers.Complex) and b.imag == 0:
497 b = b.real
498 if isinstance(b, float):
499 b = a.from_float(b)
500 try:
Mark Dickinsond058cd22008-02-10 21:29:51 +0000501 # XXX: If b <: Real but not <: Rational, this is likely
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000502 # to fall back to a float. If the actual values differ by
503 # less than MIN_FLOAT, this could falsely call them equal,
504 # which would make <= inconsistent with ==. Better ways of
505 # doing this are welcome.
506 diff = a - b
507 except TypeError:
508 return NotImplemented
Mark Dickinsond058cd22008-02-10 21:29:51 +0000509 if isinstance(diff, Rational):
Jeffrey Yasskind7b00332008-01-15 07:46:24 +0000510 return op(diff.numerator, 0)
511 return op(diff, 0)
512
513 def __lt__(a, b):
514 """a < b"""
515 return a._subtractAndCompareToZero(b, operator.lt)
516
517 def __gt__(a, b):
518 """a > b"""
519 return a._subtractAndCompareToZero(b, operator.gt)
520
521 def __le__(a, b):
522 """a <= b"""
523 return a._subtractAndCompareToZero(b, operator.le)
524
525 def __ge__(a, b):
526 """a >= b"""
527 return a._subtractAndCompareToZero(b, operator.ge)
528
529 def __nonzero__(a):
530 """a != 0"""
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000531 return a._numerator != 0
Raymond Hettingera6216742008-01-25 00:21:54 +0000532
533 # support for pickling, copy, and deepcopy
534
535 def __reduce__(self):
536 return (self.__class__, (str(self),))
537
538 def __copy__(self):
Mark Dickinsond058cd22008-02-10 21:29:51 +0000539 if type(self) == Fraction:
Raymond Hettingera6216742008-01-25 00:21:54 +0000540 return self # I'm immutable; therefore I am my own clone
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000541 return self.__class__(self._numerator, self._denominator)
Raymond Hettingera6216742008-01-25 00:21:54 +0000542
543 def __deepcopy__(self, memo):
Mark Dickinsond058cd22008-02-10 21:29:51 +0000544 if type(self) == Fraction:
Raymond Hettingera6216742008-01-25 00:21:54 +0000545 return self # My components are also immutable
Jeffrey Yasskin339f5e32008-02-14 07:49:25 +0000546 return self.__class__(self._numerator, self._denominator)