blob: fc8a12c0144ab06d92c690c953775719944a9ea9 [file] [log] [blame]
Guido van Rossum7736b5b2008-01-15 21:44:53 +00001# Originally contributed by Sjoerd Mullender.
2# Significantly modified by Jeffrey Yasskin <jyasskin at gmail.com>.
3
Christian Heimes3feef612008-02-11 06:19:17 +00004"""Fraction, infinite-precision, real numbers."""
Guido van Rossum7736b5b2008-01-15 21:44:53 +00005
Mark Dickinson98127c32010-04-03 11:18:52 +00006from decimal import Decimal
Guido van Rossum7736b5b2008-01-15 21:44:53 +00007import math
8import numbers
9import operator
Christian Heimes587c2bf2008-01-19 16:21:02 +000010import re
Guido van Rossum7736b5b2008-01-15 21:44:53 +000011
Raymond Hettingere580f5c2008-05-08 16:03:04 +000012__all__ = ['Fraction', 'gcd']
Guido van Rossum7736b5b2008-01-15 21:44:53 +000013
Guido van Rossum7736b5b2008-01-15 21:44:53 +000014
15
Christian Heimesaf98da12008-01-27 15:18:18 +000016def gcd(a, b):
17 """Calculate the Greatest Common Divisor of a and b.
Guido van Rossum7736b5b2008-01-15 21:44:53 +000018
19 Unless b==0, the result will have the same sign as b (so that when
20 b is divided by it, the result comes out positive).
21 """
22 while b:
23 a, b = b, a%b
24 return a
25
26
Christian Heimes292d3512008-02-03 16:51:08 +000027_RATIONAL_FORMAT = re.compile(r"""
28 \A\s* # optional whitespace at the start, then
29 (?P<sign>[-+]?) # an optional sign, then
30 (?=\d|\.\d) # lookahead for digit or .digit
31 (?P<num>\d*) # numerator (possibly empty)
Mark Dickinsoncf63f2f2009-04-22 17:50:21 +000032 (?: # followed by
33 (?:/(?P<denom>\d+))? # an optional denominator
Christian Heimes292d3512008-02-03 16:51:08 +000034 | # or
Mark Dickinsoncf63f2f2009-04-22 17:50:21 +000035 (?:\.(?P<decimal>\d*))? # an optional fractional part
36 (?:E(?P<exp>[-+]?\d+))? # and optional exponent
37 )
Christian Heimes292d3512008-02-03 16:51:08 +000038 \s*\Z # and optional whitespace to finish
Mark Dickinsoncf63f2f2009-04-22 17:50:21 +000039""", re.VERBOSE | re.IGNORECASE)
Christian Heimes587c2bf2008-01-19 16:21:02 +000040
41
Christian Heimes3feef612008-02-11 06:19:17 +000042class Fraction(numbers.Rational):
Guido van Rossum7736b5b2008-01-15 21:44:53 +000043 """This class implements rational numbers.
44
Mark Dickinson98127c32010-04-03 11:18:52 +000045 In the two-argument form of the constructor, Fraction(8, 6) will
46 produce a rational number equivalent to 4/3. Both arguments must
47 be Rational. The numerator defaults to 0 and the denominator
48 defaults to 1 so that Fraction(3) == 3 and Fraction() == 0.
Guido van Rossum7736b5b2008-01-15 21:44:53 +000049
Mark Dickinson98127c32010-04-03 11:18:52 +000050 Fractions can also be constructed from:
51
52 - numeric strings similar to those accepted by the
53 float constructor (for example, '-2.3' or '1e10')
54
55 - strings of the form '123/456'
56
57 - float and Decimal instances
58
59 - other Rational instances (including integers)
Christian Heimes587c2bf2008-01-19 16:21:02 +000060
Guido van Rossum7736b5b2008-01-15 21:44:53 +000061 """
62
Christian Heimes400adb02008-02-01 08:12:03 +000063 __slots__ = ('_numerator', '_denominator')
Guido van Rossum7736b5b2008-01-15 21:44:53 +000064
Christian Heimes587c2bf2008-01-19 16:21:02 +000065 # We're immutable, so use __new__ not __init__
Mark Dickinsond4d95f82009-04-24 14:06:19 +000066 def __new__(cls, numerator=0, denominator=None):
Christian Heimes587c2bf2008-01-19 16:21:02 +000067 """Constructs a Rational.
68
Mark Dickinson98127c32010-04-03 11:18:52 +000069 Takes a string like '3/2' or '1.5', another Rational instance, a
70 numerator/denominator pair, or a float.
71
72 Examples
73 --------
74
75 >>> Fraction(10, -8)
76 Fraction(-5, 4)
77 >>> Fraction(Fraction(1, 7), 5)
78 Fraction(1, 35)
79 >>> Fraction(Fraction(1, 7), Fraction(2, 3))
80 Fraction(3, 14)
81 >>> Fraction('314')
82 Fraction(314, 1)
83 >>> Fraction('-35/4')
84 Fraction(-35, 4)
85 >>> Fraction('3.1415') # conversion from numeric string
86 Fraction(6283, 2000)
87 >>> Fraction('-47e-2') # string may include a decimal exponent
88 Fraction(-47, 100)
89 >>> Fraction(1.47) # direct construction from float (exact conversion)
90 Fraction(6620291452234629, 4503599627370496)
91 >>> Fraction(2.25)
92 Fraction(9, 4)
93 >>> Fraction(Decimal('1.47'))
94 Fraction(147, 100)
Christian Heimes587c2bf2008-01-19 16:21:02 +000095
96 """
Christian Heimes3feef612008-02-11 06:19:17 +000097 self = super(Fraction, cls).__new__(cls)
Christian Heimes587c2bf2008-01-19 16:21:02 +000098
Mark Dickinsond4d95f82009-04-24 14:06:19 +000099 if denominator is None:
100 if isinstance(numerator, numbers.Rational):
101 self._numerator = numerator.numerator
102 self._denominator = numerator.denominator
103 return self
104
Mark Dickinson98127c32010-04-03 11:18:52 +0000105 elif isinstance(numerator, float):
106 # Exact conversion from float
107 value = Fraction.from_float(numerator)
108 self._numerator = value._numerator
109 self._denominator = value._denominator
110 return self
111
112 elif isinstance(numerator, Decimal):
113 value = Fraction.from_decimal(numerator)
114 self._numerator = value._numerator
115 self._denominator = value._denominator
116 return self
117
Mark Dickinsond4d95f82009-04-24 14:06:19 +0000118 elif isinstance(numerator, str):
Christian Heimes587c2bf2008-01-19 16:21:02 +0000119 # Handle construction from strings.
Mark Dickinsoncf63f2f2009-04-22 17:50:21 +0000120 m = _RATIONAL_FORMAT.match(numerator)
Christian Heimes587c2bf2008-01-19 16:21:02 +0000121 if m is None:
Mark Dickinsoncf63f2f2009-04-22 17:50:21 +0000122 raise ValueError('Invalid literal for Fraction: %r' %
123 numerator)
124 numerator = int(m.group('num') or '0')
125 denom = m.group('denom')
126 if denom:
127 denominator = int(denom)
Christian Heimesaf98da12008-01-27 15:18:18 +0000128 else:
Mark Dickinsoncf63f2f2009-04-22 17:50:21 +0000129 denominator = 1
130 decimal = m.group('decimal')
131 if decimal:
132 scale = 10**len(decimal)
133 numerator = numerator * scale + int(decimal)
134 denominator *= scale
135 exp = m.group('exp')
136 if exp:
137 exp = int(exp)
138 if exp >= 0:
139 numerator *= 10**exp
140 else:
141 denominator *= 10**-exp
Christian Heimes587c2bf2008-01-19 16:21:02 +0000142 if m.group('sign') == '-':
143 numerator = -numerator
144
Mark Dickinsond4d95f82009-04-24 14:06:19 +0000145 else:
146 raise TypeError("argument should be a string "
147 "or a Rational instance")
148
149 elif (isinstance(numerator, numbers.Rational) and
150 isinstance(denominator, numbers.Rational)):
151 numerator, denominator = (
152 numerator.numerator * denominator.denominator,
153 denominator.numerator * numerator.denominator
154 )
155 else:
156 raise TypeError("both arguments should be "
157 "Rational instances")
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000158
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000159 if denominator == 0:
Christian Heimes3feef612008-02-11 06:19:17 +0000160 raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
Christian Heimesaf98da12008-01-27 15:18:18 +0000161 g = gcd(numerator, denominator)
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000162 self._numerator = numerator // g
163 self._denominator = denominator // g
Christian Heimes587c2bf2008-01-19 16:21:02 +0000164 return self
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000165
166 @classmethod
167 def from_float(cls, f):
Christian Heimes587c2bf2008-01-19 16:21:02 +0000168 """Converts a finite float to a rational number, exactly.
169
Christian Heimes3feef612008-02-11 06:19:17 +0000170 Beware that Fraction.from_float(0.3) != Fraction(3, 10).
Christian Heimes587c2bf2008-01-19 16:21:02 +0000171
172 """
Georg Brandl2ee470f2008-07-16 12:55:28 +0000173 if isinstance(f, numbers.Integral):
Georg Brandl3a9b0622009-01-03 22:07:57 +0000174 return cls(f)
Georg Brandl2ee470f2008-07-16 12:55:28 +0000175 elif not isinstance(f, float):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000176 raise TypeError("%s.from_float() only takes floats, not %r (%s)" %
177 (cls.__name__, f, type(f).__name__))
178 if math.isnan(f) or math.isinf(f):
179 raise TypeError("Cannot convert %r to %s." % (f, cls.__name__))
Christian Heimes26855632008-01-27 23:50:43 +0000180 return cls(*f.as_integer_ratio())
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000181
Christian Heimes587c2bf2008-01-19 16:21:02 +0000182 @classmethod
183 def from_decimal(cls, dec):
184 """Converts a finite Decimal instance to a rational number, exactly."""
185 from decimal import Decimal
Georg Brandl2ee470f2008-07-16 12:55:28 +0000186 if isinstance(dec, numbers.Integral):
187 dec = Decimal(int(dec))
188 elif not isinstance(dec, Decimal):
Christian Heimes587c2bf2008-01-19 16:21:02 +0000189 raise TypeError(
190 "%s.from_decimal() only takes Decimals, not %r (%s)" %
191 (cls.__name__, dec, type(dec).__name__))
192 if not dec.is_finite():
193 # Catches infinities and nans.
194 raise TypeError("Cannot convert %s to %s." % (dec, cls.__name__))
195 sign, digits, exp = dec.as_tuple()
196 digits = int(''.join(map(str, digits)))
197 if sign:
198 digits = -digits
199 if exp >= 0:
200 return cls(digits * 10 ** exp)
201 else:
202 return cls(digits, 10 ** -exp)
203
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000204 def limit_denominator(self, max_denominator=1000000):
205 """Closest Fraction to self with denominator at most max_denominator.
Christian Heimesbbffeb62008-01-24 09:42:52 +0000206
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000207 >>> Fraction('3.141592653589793').limit_denominator(10)
208 Fraction(22, 7)
209 >>> Fraction('3.141592653589793').limit_denominator(100)
210 Fraction(311, 99)
Mark Dickinsondfb15622009-11-23 16:27:17 +0000211 >>> Fraction(4321, 8765).limit_denominator(10000)
212 Fraction(4321, 8765)
Christian Heimesbbffeb62008-01-24 09:42:52 +0000213
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000214 """
215 # Algorithm notes: For any real number x, define a *best upper
216 # approximation* to x to be a rational number p/q such that:
217 #
218 # (1) p/q >= x, and
219 # (2) if p/q > r/s >= x then s > q, for any rational r/s.
220 #
221 # Define *best lower approximation* similarly. Then it can be
222 # proved that a rational number is a best upper or lower
223 # approximation to x if, and only if, it is a convergent or
224 # semiconvergent of the (unique shortest) continued fraction
225 # associated to x.
226 #
227 # To find a best rational approximation with denominator <= M,
228 # we find the best upper and lower approximations with
229 # denominator <= M and take whichever of these is closer to x.
230 # In the event of a tie, the bound with smaller denominator is
231 # chosen. If both denominators are equal (which can happen
232 # only when max_denominator == 1 and self is midway between
233 # two integers) the lower bound---i.e., the floor of self, is
234 # taken.
235
236 if max_denominator < 1:
237 raise ValueError("max_denominator should be at least 1")
238 if self._denominator <= max_denominator:
239 return Fraction(self)
240
241 p0, q0, p1, q1 = 0, 1, 1, 0
242 n, d = self._numerator, self._denominator
243 while True:
244 a = n//d
245 q2 = q0+a*q1
246 if q2 > max_denominator:
Christian Heimesbbffeb62008-01-24 09:42:52 +0000247 break
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000248 p0, q0, p1, q1 = p1, q1, p0+a*p1, q2
249 n, d = d, n-a*d
250
251 k = (max_denominator-q0)//q1
252 bound1 = Fraction(p0+k*p1, q0+k*q1)
253 bound2 = Fraction(p1, q1)
254 if abs(bound2 - self) <= abs(bound1-self):
255 return bound2
256 else:
257 return bound1
Christian Heimesbbffeb62008-01-24 09:42:52 +0000258
Christian Heimes400adb02008-02-01 08:12:03 +0000259 @property
260 def numerator(a):
261 return a._numerator
262
263 @property
264 def denominator(a):
265 return a._denominator
266
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000267 def __repr__(self):
268 """repr(self)"""
Benjamin Peterson41181742008-07-02 20:22:54 +0000269 return ('Fraction(%s, %s)' % (self._numerator, self._denominator))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000270
271 def __str__(self):
272 """str(self)"""
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000273 if self._denominator == 1:
274 return str(self._numerator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000275 else:
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000276 return '%s/%s' % (self._numerator, self._denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000277
278 def _operator_fallbacks(monomorphic_operator, fallback_operator):
279 """Generates forward and reverse operators given a purely-rational
280 operator and a function from the operator module.
281
282 Use this like:
283 __op__, __rop__ = _operator_fallbacks(just_rational_op, operator.op)
284
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000285 In general, we want to implement the arithmetic operations so
286 that mixed-mode operations either call an implementation whose
287 author knew about the types of both arguments, or convert both
288 to the nearest built in type and do the operation there. In
Christian Heimes3feef612008-02-11 06:19:17 +0000289 Fraction, that means that we define __add__ and __radd__ as:
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000290
291 def __add__(self, other):
Christian Heimes400adb02008-02-01 08:12:03 +0000292 # Both types have numerators/denominator attributes,
293 # so do the operation directly
Christian Heimes3feef612008-02-11 06:19:17 +0000294 if isinstance(other, (int, Fraction)):
295 return Fraction(self.numerator * other.denominator +
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000296 other.numerator * self.denominator,
297 self.denominator * other.denominator)
Christian Heimes400adb02008-02-01 08:12:03 +0000298 # float and complex don't have those operations, but we
299 # know about those types, so special case them.
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000300 elif isinstance(other, float):
301 return float(self) + other
302 elif isinstance(other, complex):
303 return complex(self) + other
Christian Heimes400adb02008-02-01 08:12:03 +0000304 # Let the other type take over.
305 return NotImplemented
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000306
307 def __radd__(self, other):
308 # radd handles more types than add because there's
309 # nothing left to fall back to.
Christian Heimes3feef612008-02-11 06:19:17 +0000310 if isinstance(other, numbers.Rational):
311 return Fraction(self.numerator * other.denominator +
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000312 other.numerator * self.denominator,
313 self.denominator * other.denominator)
314 elif isinstance(other, Real):
315 return float(other) + float(self)
316 elif isinstance(other, Complex):
317 return complex(other) + complex(self)
Christian Heimes400adb02008-02-01 08:12:03 +0000318 return NotImplemented
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000319
320
321 There are 5 different cases for a mixed-type addition on
Christian Heimes3feef612008-02-11 06:19:17 +0000322 Fraction. I'll refer to all of the above code that doesn't
323 refer to Fraction, float, or complex as "boilerplate". 'r'
324 will be an instance of Fraction, which is a subtype of
325 Rational (r : Fraction <: Rational), and b : B <:
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000326 Complex. The first three involve 'r + b':
327
Christian Heimes3feef612008-02-11 06:19:17 +0000328 1. If B <: Fraction, int, float, or complex, we handle
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000329 that specially, and all is well.
Christian Heimes3feef612008-02-11 06:19:17 +0000330 2. If Fraction falls back to the boilerplate code, and it
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000331 were to return a value from __add__, we'd miss the
332 possibility that B defines a more intelligent __radd__,
333 so the boilerplate should return NotImplemented from
Christian Heimes3feef612008-02-11 06:19:17 +0000334 __add__. In particular, we don't handle Rational
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000335 here, even though we could get an exact answer, in case
336 the other type wants to do something special.
Christian Heimes3feef612008-02-11 06:19:17 +0000337 3. If B <: Fraction, Python tries B.__radd__ before
338 Fraction.__add__. This is ok, because it was
339 implemented with knowledge of Fraction, so it can
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000340 handle those instances before delegating to Real or
341 Complex.
342
343 The next two situations describe 'b + r'. We assume that b
Christian Heimes3feef612008-02-11 06:19:17 +0000344 didn't know about Fraction in its implementation, and that it
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000345 uses similar boilerplate code:
346
Christian Heimes3feef612008-02-11 06:19:17 +0000347 4. If B <: Rational, then __radd_ converts both to the
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000348 builtin rational type (hey look, that's us) and
349 proceeds.
350 5. Otherwise, __radd__ tries to find the nearest common
351 base ABC, and fall back to its builtin type. Since this
352 class doesn't subclass a concrete type, there's no
353 implementation to fall back to, so we need to try as
354 hard as possible to return an actual value, or the user
355 will get a TypeError.
356
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000357 """
358 def forward(a, b):
Christian Heimes3feef612008-02-11 06:19:17 +0000359 if isinstance(b, (int, Fraction)):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000360 return monomorphic_operator(a, b)
361 elif isinstance(b, float):
362 return fallback_operator(float(a), b)
363 elif isinstance(b, complex):
364 return fallback_operator(complex(a), b)
365 else:
366 return NotImplemented
367 forward.__name__ = '__' + fallback_operator.__name__ + '__'
368 forward.__doc__ = monomorphic_operator.__doc__
369
370 def reverse(b, a):
Christian Heimes3feef612008-02-11 06:19:17 +0000371 if isinstance(a, numbers.Rational):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000372 # Includes ints.
373 return monomorphic_operator(a, b)
374 elif isinstance(a, numbers.Real):
375 return fallback_operator(float(a), float(b))
376 elif isinstance(a, numbers.Complex):
377 return fallback_operator(complex(a), complex(b))
378 else:
379 return NotImplemented
380 reverse.__name__ = '__r' + fallback_operator.__name__ + '__'
381 reverse.__doc__ = monomorphic_operator.__doc__
382
383 return forward, reverse
384
385 def _add(a, b):
386 """a + b"""
Christian Heimes3feef612008-02-11 06:19:17 +0000387 return Fraction(a.numerator * b.denominator +
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000388 b.numerator * a.denominator,
389 a.denominator * b.denominator)
390
391 __add__, __radd__ = _operator_fallbacks(_add, operator.add)
392
393 def _sub(a, b):
394 """a - b"""
Christian Heimes3feef612008-02-11 06:19:17 +0000395 return Fraction(a.numerator * b.denominator -
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000396 b.numerator * a.denominator,
397 a.denominator * b.denominator)
398
399 __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub)
400
401 def _mul(a, b):
402 """a * b"""
Christian Heimes3feef612008-02-11 06:19:17 +0000403 return Fraction(a.numerator * b.numerator, a.denominator * b.denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000404
405 __mul__, __rmul__ = _operator_fallbacks(_mul, operator.mul)
406
407 def _div(a, b):
408 """a / b"""
Christian Heimes3feef612008-02-11 06:19:17 +0000409 return Fraction(a.numerator * b.denominator,
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000410 a.denominator * b.numerator)
411
412 __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000413
414 def __floordiv__(a, b):
415 """a // b"""
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000416 return math.floor(a / b)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000417
418 def __rfloordiv__(b, a):
419 """a // b"""
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000420 return math.floor(a / b)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000421
Christian Heimes969fe572008-01-25 11:23:10 +0000422 def __mod__(a, b):
423 """a % b"""
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000424 div = a // b
425 return a - b * div
426
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000427 def __rmod__(b, a):
428 """a % b"""
Christian Heimes969fe572008-01-25 11:23:10 +0000429 div = a // b
430 return a - b * div
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000431
432 def __pow__(a, b):
433 """a ** b
434
435 If b is not an integer, the result will be a float or complex
436 since roots are generally irrational. If b is an integer, the
437 result will be rational.
438
439 """
Christian Heimes3feef612008-02-11 06:19:17 +0000440 if isinstance(b, numbers.Rational):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000441 if b.denominator == 1:
442 power = b.numerator
443 if power >= 0:
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000444 return Fraction(a._numerator ** power,
445 a._denominator ** power)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000446 else:
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000447 return Fraction(a._denominator ** -power,
448 a._numerator ** -power)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000449 else:
450 # A fractional power will generally produce an
451 # irrational number.
452 return float(a) ** float(b)
453 else:
454 return float(a) ** b
455
456 def __rpow__(b, a):
457 """a ** b"""
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000458 if b._denominator == 1 and b._numerator >= 0:
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000459 # If a is an int, keep it that way if possible.
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000460 return a ** b._numerator
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000461
Christian Heimes3feef612008-02-11 06:19:17 +0000462 if isinstance(a, numbers.Rational):
463 return Fraction(a.numerator, a.denominator) ** b
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000464
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000465 if b._denominator == 1:
466 return a ** b._numerator
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000467
468 return a ** float(b)
469
470 def __pos__(a):
Christian Heimes3feef612008-02-11 06:19:17 +0000471 """+a: Coerces a subclass instance to Fraction"""
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000472 return Fraction(a._numerator, a._denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000473
474 def __neg__(a):
475 """-a"""
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000476 return Fraction(-a._numerator, a._denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000477
478 def __abs__(a):
479 """abs(a)"""
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000480 return Fraction(abs(a._numerator), a._denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000481
482 def __trunc__(a):
483 """trunc(a)"""
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000484 if a._numerator < 0:
485 return -(-a._numerator // a._denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000486 else:
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000487 return a._numerator // a._denominator
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000488
489 def __floor__(a):
490 """Will be math.floor(a) in 3.0."""
491 return a.numerator // a.denominator
492
493 def __ceil__(a):
494 """Will be math.ceil(a) in 3.0."""
495 # The negations cleverly convince floordiv to return the ceiling.
496 return -(-a.numerator // a.denominator)
497
498 def __round__(self, ndigits=None):
499 """Will be round(self, ndigits) in 3.0.
500
501 Rounds half toward even.
502 """
503 if ndigits is None:
504 floor, remainder = divmod(self.numerator, self.denominator)
505 if remainder * 2 < self.denominator:
506 return floor
507 elif remainder * 2 > self.denominator:
508 return floor + 1
509 # Deal with the half case:
510 elif floor % 2 == 0:
511 return floor
512 else:
513 return floor + 1
514 shift = 10**abs(ndigits)
515 # See _operator_fallbacks.forward to check that the results of
Christian Heimes3feef612008-02-11 06:19:17 +0000516 # these operations will always be Fraction and therefore have
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000517 # round().
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000518 if ndigits > 0:
Christian Heimes3feef612008-02-11 06:19:17 +0000519 return Fraction(round(self * shift), shift)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000520 else:
Christian Heimes3feef612008-02-11 06:19:17 +0000521 return Fraction(round(self / shift) * shift)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000522
523 def __hash__(self):
524 """hash(self)
525
526 Tricky because values that are exactly representable as a
527 float must have the same hash as that float.
528
529 """
Christian Heimes969fe572008-01-25 11:23:10 +0000530 # XXX since this method is expensive, consider caching the result
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000531 if self._denominator == 1:
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000532 # Get integers right.
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000533 return hash(self._numerator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000534 # Expensive check, but definitely correct.
535 if self == float(self):
536 return hash(float(self))
537 else:
538 # Use tuple's hash to avoid a high collision rate on
539 # simple fractions.
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000540 return hash((self._numerator, self._denominator))
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000541
542 def __eq__(a, b):
543 """a == b"""
Christian Heimes3feef612008-02-11 06:19:17 +0000544 if isinstance(b, numbers.Rational):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000545 return (a._numerator == b.numerator and
546 a._denominator == b.denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000547 if isinstance(b, numbers.Complex) and b.imag == 0:
548 b = b.real
549 if isinstance(b, float):
Mark Dickinson85424c92009-07-18 14:41:42 +0000550 if math.isnan(b) or math.isinf(b):
551 # comparisons with an infinity or nan should behave in
552 # the same way for any finite a, so treat a as zero.
553 return 0.0 == b
554 else:
555 return a == a.from_float(b)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000556 else:
Mark Dickinson85424c92009-07-18 14:41:42 +0000557 # Since a doesn't know how to compare with b, let's give b
558 # a chance to compare itself with a.
559 return NotImplemented
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000560
Mark Dickinson85424c92009-07-18 14:41:42 +0000561 def _richcmp(self, other, op):
562 """Helper for comparison operators, for internal use only.
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000563
Mark Dickinson85424c92009-07-18 14:41:42 +0000564 Implement comparison between a Rational instance `self`, and
565 either another Rational instance or a float `other`. If
566 `other` is not a Rational instance or a float, return
567 NotImplemented. `op` should be one of the six standard
568 comparison operators.
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000569
570 """
Mark Dickinson85424c92009-07-18 14:41:42 +0000571 # convert other to a Rational instance where reasonable.
572 if isinstance(other, numbers.Rational):
573 return op(self._numerator * other.denominator,
574 self._denominator * other.numerator)
Mark Dickinson85424c92009-07-18 14:41:42 +0000575 if isinstance(other, float):
576 if math.isnan(other) or math.isinf(other):
577 return op(0.0, other)
578 else:
579 return op(self, self.from_float(other))
580 else:
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000581 return NotImplemented
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000582
583 def __lt__(a, b):
584 """a < b"""
Mark Dickinson85424c92009-07-18 14:41:42 +0000585 return a._richcmp(b, operator.lt)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000586
587 def __gt__(a, b):
588 """a > b"""
Mark Dickinson85424c92009-07-18 14:41:42 +0000589 return a._richcmp(b, operator.gt)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000590
591 def __le__(a, b):
592 """a <= b"""
Mark Dickinson85424c92009-07-18 14:41:42 +0000593 return a._richcmp(b, operator.le)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000594
595 def __ge__(a, b):
596 """a >= b"""
Mark Dickinson85424c92009-07-18 14:41:42 +0000597 return a._richcmp(b, operator.ge)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000598
599 def __bool__(a):
600 """a != 0"""
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000601 return a._numerator != 0
Christian Heimes969fe572008-01-25 11:23:10 +0000602
603 # support for pickling, copy, and deepcopy
604
605 def __reduce__(self):
606 return (self.__class__, (str(self),))
607
608 def __copy__(self):
Christian Heimes3feef612008-02-11 06:19:17 +0000609 if type(self) == Fraction:
Christian Heimes969fe572008-01-25 11:23:10 +0000610 return self # I'm immutable; therefore I am my own clone
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000611 return self.__class__(self._numerator, self._denominator)
Christian Heimes969fe572008-01-25 11:23:10 +0000612
613 def __deepcopy__(self, memo):
Christian Heimes3feef612008-02-11 06:19:17 +0000614 if type(self) == Fraction:
Christian Heimes969fe572008-01-25 11:23:10 +0000615 return self # My components are also immutable
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000616 return self.__class__(self._numerator, self._denominator)