blob: 4bbfc434f7d182a9ba4486fae85b59af6de59067 [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
Mark Dickinsondc787d22010-05-23 13:33:13 +000011import sys
Guido van Rossum7736b5b2008-01-15 21:44:53 +000012
Raymond Hettingere580f5c2008-05-08 16:03:04 +000013__all__ = ['Fraction', 'gcd']
Guido van Rossum7736b5b2008-01-15 21:44:53 +000014
Guido van Rossum7736b5b2008-01-15 21:44:53 +000015
16
Christian Heimesaf98da12008-01-27 15:18:18 +000017def gcd(a, b):
18 """Calculate the Greatest Common Divisor of a and b.
Guido van Rossum7736b5b2008-01-15 21:44:53 +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 """
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +030023 import warnings
24 warnings.warn('fractions.gcd() is deprecated. Use math.gcd() instead.',
25 DeprecationWarning, 2)
26 if type(a) is int is type(b):
27 if (b or a) < 0:
28 return -math.gcd(a, b)
29 return math.gcd(a, b)
30 return _gcd(a, b)
31
32def _gcd(a, b):
33 # Supports non-integers for backward compatibility.
Guido van Rossum7736b5b2008-01-15 21:44:53 +000034 while b:
35 a, b = b, a%b
36 return a
37
Mark Dickinsondc787d22010-05-23 13:33:13 +000038# Constants related to the hash implementation; hash(x) is based
39# on the reduction of x modulo the prime _PyHASH_MODULUS.
40_PyHASH_MODULUS = sys.hash_info.modulus
41# Value to be used for rationals that reduce to infinity modulo
42# _PyHASH_MODULUS.
43_PyHASH_INF = sys.hash_info.inf
Guido van Rossum7736b5b2008-01-15 21:44:53 +000044
Christian Heimes292d3512008-02-03 16:51:08 +000045_RATIONAL_FORMAT = re.compile(r"""
46 \A\s* # optional whitespace at the start, then
47 (?P<sign>[-+]?) # an optional sign, then
48 (?=\d|\.\d) # lookahead for digit or .digit
49 (?P<num>\d*) # numerator (possibly empty)
Mark Dickinsoncf63f2f2009-04-22 17:50:21 +000050 (?: # followed by
51 (?:/(?P<denom>\d+))? # an optional denominator
Christian Heimes292d3512008-02-03 16:51:08 +000052 | # or
Mark Dickinsoncf63f2f2009-04-22 17:50:21 +000053 (?:\.(?P<decimal>\d*))? # an optional fractional part
54 (?:E(?P<exp>[-+]?\d+))? # and optional exponent
55 )
Christian Heimes292d3512008-02-03 16:51:08 +000056 \s*\Z # and optional whitespace to finish
Mark Dickinsoncf63f2f2009-04-22 17:50:21 +000057""", re.VERBOSE | re.IGNORECASE)
Christian Heimes587c2bf2008-01-19 16:21:02 +000058
59
Christian Heimes3feef612008-02-11 06:19:17 +000060class Fraction(numbers.Rational):
Guido van Rossum7736b5b2008-01-15 21:44:53 +000061 """This class implements rational numbers.
62
Mark Dickinson98127c32010-04-03 11:18:52 +000063 In the two-argument form of the constructor, Fraction(8, 6) will
64 produce a rational number equivalent to 4/3. Both arguments must
65 be Rational. The numerator defaults to 0 and the denominator
66 defaults to 1 so that Fraction(3) == 3 and Fraction() == 0.
Guido van Rossum7736b5b2008-01-15 21:44:53 +000067
Mark Dickinson98127c32010-04-03 11:18:52 +000068 Fractions can also be constructed from:
69
70 - numeric strings similar to those accepted by the
71 float constructor (for example, '-2.3' or '1e10')
72
73 - strings of the form '123/456'
74
75 - float and Decimal instances
76
77 - other Rational instances (including integers)
Christian Heimes587c2bf2008-01-19 16:21:02 +000078
Guido van Rossum7736b5b2008-01-15 21:44:53 +000079 """
80
Christian Heimes400adb02008-02-01 08:12:03 +000081 __slots__ = ('_numerator', '_denominator')
Guido van Rossum7736b5b2008-01-15 21:44:53 +000082
Christian Heimes587c2bf2008-01-19 16:21:02 +000083 # We're immutable, so use __new__ not __init__
Mark Dickinson7caf9082016-08-23 16:16:52 +010084 def __new__(cls, numerator=0, denominator=None, *, _normalize=True):
Christian Heimes587c2bf2008-01-19 16:21:02 +000085 """Constructs a Rational.
86
Mark Dickinson98127c32010-04-03 11:18:52 +000087 Takes a string like '3/2' or '1.5', another Rational instance, a
88 numerator/denominator pair, or a float.
89
90 Examples
91 --------
92
93 >>> Fraction(10, -8)
94 Fraction(-5, 4)
95 >>> Fraction(Fraction(1, 7), 5)
96 Fraction(1, 35)
97 >>> Fraction(Fraction(1, 7), Fraction(2, 3))
98 Fraction(3, 14)
99 >>> Fraction('314')
100 Fraction(314, 1)
101 >>> Fraction('-35/4')
102 Fraction(-35, 4)
103 >>> Fraction('3.1415') # conversion from numeric string
104 Fraction(6283, 2000)
105 >>> Fraction('-47e-2') # string may include a decimal exponent
106 Fraction(-47, 100)
107 >>> Fraction(1.47) # direct construction from float (exact conversion)
108 Fraction(6620291452234629, 4503599627370496)
109 >>> Fraction(2.25)
110 Fraction(9, 4)
111 >>> Fraction(Decimal('1.47'))
112 Fraction(147, 100)
Christian Heimes587c2bf2008-01-19 16:21:02 +0000113
114 """
Christian Heimes3feef612008-02-11 06:19:17 +0000115 self = super(Fraction, cls).__new__(cls)
Christian Heimes587c2bf2008-01-19 16:21:02 +0000116
Mark Dickinsond4d95f82009-04-24 14:06:19 +0000117 if denominator is None:
Georg Brandl40f97352014-09-24 08:37:55 +0200118 if type(numerator) is int:
119 self._numerator = numerator
120 self._denominator = 1
121 return self
122
123 elif isinstance(numerator, numbers.Rational):
Mark Dickinsond4d95f82009-04-24 14:06:19 +0000124 self._numerator = numerator.numerator
125 self._denominator = numerator.denominator
126 return self
127
Serhiy Storchaka0d250bc2015-12-29 22:34:23 +0200128 elif isinstance(numerator, (float, Decimal)):
129 # Exact conversion
130 self._numerator, self._denominator = numerator.as_integer_ratio()
Mark Dickinson98127c32010-04-03 11:18:52 +0000131 return self
132
Mark Dickinsond4d95f82009-04-24 14:06:19 +0000133 elif isinstance(numerator, str):
Christian Heimes587c2bf2008-01-19 16:21:02 +0000134 # Handle construction from strings.
Mark Dickinsoncf63f2f2009-04-22 17:50:21 +0000135 m = _RATIONAL_FORMAT.match(numerator)
Christian Heimes587c2bf2008-01-19 16:21:02 +0000136 if m is None:
Mark Dickinsoncf63f2f2009-04-22 17:50:21 +0000137 raise ValueError('Invalid literal for Fraction: %r' %
138 numerator)
139 numerator = int(m.group('num') or '0')
140 denom = m.group('denom')
141 if denom:
142 denominator = int(denom)
Christian Heimesaf98da12008-01-27 15:18:18 +0000143 else:
Mark Dickinsoncf63f2f2009-04-22 17:50:21 +0000144 denominator = 1
145 decimal = m.group('decimal')
146 if decimal:
147 scale = 10**len(decimal)
148 numerator = numerator * scale + int(decimal)
149 denominator *= scale
150 exp = m.group('exp')
151 if exp:
152 exp = int(exp)
153 if exp >= 0:
154 numerator *= 10**exp
155 else:
156 denominator *= 10**-exp
Christian Heimes587c2bf2008-01-19 16:21:02 +0000157 if m.group('sign') == '-':
158 numerator = -numerator
159
Mark Dickinsond4d95f82009-04-24 14:06:19 +0000160 else:
161 raise TypeError("argument should be a string "
162 "or a Rational instance")
163
Georg Brandl40f97352014-09-24 08:37:55 +0200164 elif type(numerator) is int is type(denominator):
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300165 pass # *very* normal case
Georg Brandl40f97352014-09-24 08:37:55 +0200166
Mark Dickinsond4d95f82009-04-24 14:06:19 +0000167 elif (isinstance(numerator, numbers.Rational) and
168 isinstance(denominator, numbers.Rational)):
169 numerator, denominator = (
170 numerator.numerator * denominator.denominator,
171 denominator.numerator * numerator.denominator
172 )
173 else:
174 raise TypeError("both arguments should be "
175 "Rational instances")
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000176
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000177 if denominator == 0:
Christian Heimes3feef612008-02-11 06:19:17 +0000178 raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
Mark Dickinson3c286e22014-04-05 09:29:00 +0100179 if _normalize:
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300180 if type(numerator) is int is type(denominator):
181 # *very* normal case
182 g = math.gcd(numerator, denominator)
183 if denominator < 0:
184 g = -g
185 else:
186 g = _gcd(numerator, denominator)
Mark Dickinson3c286e22014-04-05 09:29:00 +0100187 numerator //= g
188 denominator //= g
189 self._numerator = numerator
190 self._denominator = denominator
Christian Heimes587c2bf2008-01-19 16:21:02 +0000191 return self
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000192
193 @classmethod
194 def from_float(cls, f):
Christian Heimes587c2bf2008-01-19 16:21:02 +0000195 """Converts a finite float to a rational number, exactly.
196
Christian Heimes3feef612008-02-11 06:19:17 +0000197 Beware that Fraction.from_float(0.3) != Fraction(3, 10).
Christian Heimes587c2bf2008-01-19 16:21:02 +0000198
199 """
Georg Brandl2ee470f2008-07-16 12:55:28 +0000200 if isinstance(f, numbers.Integral):
Georg Brandl3a9b0622009-01-03 22:07:57 +0000201 return cls(f)
Georg Brandl2ee470f2008-07-16 12:55:28 +0000202 elif not isinstance(f, float):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000203 raise TypeError("%s.from_float() only takes floats, not %r (%s)" %
204 (cls.__name__, f, type(f).__name__))
Christian Heimes26855632008-01-27 23:50:43 +0000205 return cls(*f.as_integer_ratio())
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000206
Christian Heimes587c2bf2008-01-19 16:21:02 +0000207 @classmethod
208 def from_decimal(cls, dec):
209 """Converts a finite Decimal instance to a rational number, exactly."""
210 from decimal import Decimal
Georg Brandl2ee470f2008-07-16 12:55:28 +0000211 if isinstance(dec, numbers.Integral):
212 dec = Decimal(int(dec))
213 elif not isinstance(dec, Decimal):
Christian Heimes587c2bf2008-01-19 16:21:02 +0000214 raise TypeError(
215 "%s.from_decimal() only takes Decimals, not %r (%s)" %
216 (cls.__name__, dec, type(dec).__name__))
Serhiy Storchaka0d250bc2015-12-29 22:34:23 +0200217 return cls(*dec.as_integer_ratio())
Christian Heimes587c2bf2008-01-19 16:21:02 +0000218
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000219 def limit_denominator(self, max_denominator=1000000):
220 """Closest Fraction to self with denominator at most max_denominator.
Christian Heimesbbffeb62008-01-24 09:42:52 +0000221
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000222 >>> Fraction('3.141592653589793').limit_denominator(10)
223 Fraction(22, 7)
224 >>> Fraction('3.141592653589793').limit_denominator(100)
225 Fraction(311, 99)
Mark Dickinsondfb15622009-11-23 16:27:17 +0000226 >>> Fraction(4321, 8765).limit_denominator(10000)
227 Fraction(4321, 8765)
Christian Heimesbbffeb62008-01-24 09:42:52 +0000228
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000229 """
230 # Algorithm notes: For any real number x, define a *best upper
231 # approximation* to x to be a rational number p/q such that:
232 #
233 # (1) p/q >= x, and
234 # (2) if p/q > r/s >= x then s > q, for any rational r/s.
235 #
236 # Define *best lower approximation* similarly. Then it can be
237 # proved that a rational number is a best upper or lower
238 # approximation to x if, and only if, it is a convergent or
239 # semiconvergent of the (unique shortest) continued fraction
240 # associated to x.
241 #
242 # To find a best rational approximation with denominator <= M,
243 # we find the best upper and lower approximations with
244 # denominator <= M and take whichever of these is closer to x.
245 # In the event of a tie, the bound with smaller denominator is
246 # chosen. If both denominators are equal (which can happen
247 # only when max_denominator == 1 and self is midway between
248 # two integers) the lower bound---i.e., the floor of self, is
249 # taken.
250
251 if max_denominator < 1:
252 raise ValueError("max_denominator should be at least 1")
253 if self._denominator <= max_denominator:
254 return Fraction(self)
255
256 p0, q0, p1, q1 = 0, 1, 1, 0
257 n, d = self._numerator, self._denominator
258 while True:
259 a = n//d
260 q2 = q0+a*q1
261 if q2 > max_denominator:
Christian Heimesbbffeb62008-01-24 09:42:52 +0000262 break
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000263 p0, q0, p1, q1 = p1, q1, p0+a*p1, q2
264 n, d = d, n-a*d
265
266 k = (max_denominator-q0)//q1
267 bound1 = Fraction(p0+k*p1, q0+k*q1)
268 bound2 = Fraction(p1, q1)
269 if abs(bound2 - self) <= abs(bound1-self):
270 return bound2
271 else:
272 return bound1
Christian Heimesbbffeb62008-01-24 09:42:52 +0000273
Christian Heimes400adb02008-02-01 08:12:03 +0000274 @property
275 def numerator(a):
276 return a._numerator
277
278 @property
279 def denominator(a):
280 return a._denominator
281
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000282 def __repr__(self):
283 """repr(self)"""
Serhiy Storchaka465e60e2014-07-25 23:36:00 +0300284 return '%s(%s, %s)' % (self.__class__.__name__,
285 self._numerator, self._denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000286
287 def __str__(self):
288 """str(self)"""
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000289 if self._denominator == 1:
290 return str(self._numerator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000291 else:
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000292 return '%s/%s' % (self._numerator, self._denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000293
294 def _operator_fallbacks(monomorphic_operator, fallback_operator):
295 """Generates forward and reverse operators given a purely-rational
296 operator and a function from the operator module.
297
298 Use this like:
299 __op__, __rop__ = _operator_fallbacks(just_rational_op, operator.op)
300
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000301 In general, we want to implement the arithmetic operations so
302 that mixed-mode operations either call an implementation whose
303 author knew about the types of both arguments, or convert both
304 to the nearest built in type and do the operation there. In
Christian Heimes3feef612008-02-11 06:19:17 +0000305 Fraction, that means that we define __add__ and __radd__ as:
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000306
307 def __add__(self, other):
Christian Heimes400adb02008-02-01 08:12:03 +0000308 # Both types have numerators/denominator attributes,
309 # so do the operation directly
Christian Heimes3feef612008-02-11 06:19:17 +0000310 if isinstance(other, (int, Fraction)):
311 return Fraction(self.numerator * other.denominator +
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000312 other.numerator * self.denominator,
313 self.denominator * other.denominator)
Christian Heimes400adb02008-02-01 08:12:03 +0000314 # float and complex don't have those operations, but we
315 # know about those types, so special case them.
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000316 elif isinstance(other, float):
317 return float(self) + other
318 elif isinstance(other, complex):
319 return complex(self) + other
Christian Heimes400adb02008-02-01 08:12:03 +0000320 # Let the other type take over.
321 return NotImplemented
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000322
323 def __radd__(self, other):
324 # radd handles more types than add because there's
325 # nothing left to fall back to.
Christian Heimes3feef612008-02-11 06:19:17 +0000326 if isinstance(other, numbers.Rational):
327 return Fraction(self.numerator * other.denominator +
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000328 other.numerator * self.denominator,
329 self.denominator * other.denominator)
330 elif isinstance(other, Real):
331 return float(other) + float(self)
332 elif isinstance(other, Complex):
333 return complex(other) + complex(self)
Christian Heimes400adb02008-02-01 08:12:03 +0000334 return NotImplemented
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000335
336
337 There are 5 different cases for a mixed-type addition on
Christian Heimes3feef612008-02-11 06:19:17 +0000338 Fraction. I'll refer to all of the above code that doesn't
339 refer to Fraction, float, or complex as "boilerplate". 'r'
340 will be an instance of Fraction, which is a subtype of
341 Rational (r : Fraction <: Rational), and b : B <:
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000342 Complex. The first three involve 'r + b':
343
Christian Heimes3feef612008-02-11 06:19:17 +0000344 1. If B <: Fraction, int, float, or complex, we handle
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000345 that specially, and all is well.
Christian Heimes3feef612008-02-11 06:19:17 +0000346 2. If Fraction falls back to the boilerplate code, and it
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000347 were to return a value from __add__, we'd miss the
348 possibility that B defines a more intelligent __radd__,
349 so the boilerplate should return NotImplemented from
Christian Heimes3feef612008-02-11 06:19:17 +0000350 __add__. In particular, we don't handle Rational
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000351 here, even though we could get an exact answer, in case
352 the other type wants to do something special.
Christian Heimes3feef612008-02-11 06:19:17 +0000353 3. If B <: Fraction, Python tries B.__radd__ before
354 Fraction.__add__. This is ok, because it was
355 implemented with knowledge of Fraction, so it can
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000356 handle those instances before delegating to Real or
357 Complex.
358
359 The next two situations describe 'b + r'. We assume that b
Christian Heimes3feef612008-02-11 06:19:17 +0000360 didn't know about Fraction in its implementation, and that it
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000361 uses similar boilerplate code:
362
Christian Heimes3feef612008-02-11 06:19:17 +0000363 4. If B <: Rational, then __radd_ converts both to the
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000364 builtin rational type (hey look, that's us) and
365 proceeds.
366 5. Otherwise, __radd__ tries to find the nearest common
367 base ABC, and fall back to its builtin type. Since this
368 class doesn't subclass a concrete type, there's no
369 implementation to fall back to, so we need to try as
370 hard as possible to return an actual value, or the user
371 will get a TypeError.
372
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000373 """
374 def forward(a, b):
Christian Heimes3feef612008-02-11 06:19:17 +0000375 if isinstance(b, (int, Fraction)):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000376 return monomorphic_operator(a, b)
377 elif isinstance(b, float):
378 return fallback_operator(float(a), b)
379 elif isinstance(b, complex):
380 return fallback_operator(complex(a), b)
381 else:
382 return NotImplemented
383 forward.__name__ = '__' + fallback_operator.__name__ + '__'
384 forward.__doc__ = monomorphic_operator.__doc__
385
386 def reverse(b, a):
Christian Heimes3feef612008-02-11 06:19:17 +0000387 if isinstance(a, numbers.Rational):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000388 # Includes ints.
389 return monomorphic_operator(a, b)
390 elif isinstance(a, numbers.Real):
391 return fallback_operator(float(a), float(b))
392 elif isinstance(a, numbers.Complex):
393 return fallback_operator(complex(a), complex(b))
394 else:
395 return NotImplemented
396 reverse.__name__ = '__r' + fallback_operator.__name__ + '__'
397 reverse.__doc__ = monomorphic_operator.__doc__
398
399 return forward, reverse
400
401 def _add(a, b):
402 """a + b"""
Georg Brandl40f97352014-09-24 08:37:55 +0200403 da, db = a.denominator, b.denominator
404 return Fraction(a.numerator * db + b.numerator * da,
405 da * db)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000406
407 __add__, __radd__ = _operator_fallbacks(_add, operator.add)
408
409 def _sub(a, b):
410 """a - b"""
Georg Brandl40f97352014-09-24 08:37:55 +0200411 da, db = a.denominator, b.denominator
412 return Fraction(a.numerator * db - b.numerator * da,
413 da * db)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000414
415 __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub)
416
417 def _mul(a, b):
418 """a * b"""
Christian Heimes3feef612008-02-11 06:19:17 +0000419 return Fraction(a.numerator * b.numerator, a.denominator * b.denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000420
421 __mul__, __rmul__ = _operator_fallbacks(_mul, operator.mul)
422
423 def _div(a, b):
424 """a / b"""
Christian Heimes3feef612008-02-11 06:19:17 +0000425 return Fraction(a.numerator * b.denominator,
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000426 a.denominator * b.numerator)
427
428 __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000429
Elias Zamaria393f1ff2018-08-26 23:59:28 -0700430 def _floordiv(a, b):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000431 """a // b"""
Stefan Behnel3a374e02019-01-02 13:22:06 +0100432 return (a.numerator * b.denominator) // (a.denominator * b.numerator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000433
Elias Zamaria393f1ff2018-08-26 23:59:28 -0700434 __floordiv__, __rfloordiv__ = _operator_fallbacks(_floordiv, operator.floordiv)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000435
Stefan Behnel3a374e02019-01-02 13:22:06 +0100436 def _divmod(a, b):
437 """(a // b, a % b)"""
438 da, db = a.denominator, b.denominator
439 div, n_mod = divmod(a.numerator * db, da * b.numerator)
440 return div, Fraction(n_mod, da * db)
441
442 __divmod__, __rdivmod__ = _operator_fallbacks(_divmod, divmod)
443
Elias Zamaria393f1ff2018-08-26 23:59:28 -0700444 def _mod(a, b):
Christian Heimes969fe572008-01-25 11:23:10 +0000445 """a % b"""
Stefan Behnel3a374e02019-01-02 13:22:06 +0100446 da, db = a.denominator, b.denominator
447 return Fraction((a.numerator * db) % (b.numerator * da), da * db)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000448
Elias Zamaria393f1ff2018-08-26 23:59:28 -0700449 __mod__, __rmod__ = _operator_fallbacks(_mod, operator.mod)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000450
451 def __pow__(a, b):
452 """a ** b
453
454 If b is not an integer, the result will be a float or complex
455 since roots are generally irrational. If b is an integer, the
456 result will be rational.
457
458 """
Christian Heimes3feef612008-02-11 06:19:17 +0000459 if isinstance(b, numbers.Rational):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000460 if b.denominator == 1:
461 power = b.numerator
462 if power >= 0:
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000463 return Fraction(a._numerator ** power,
Mark Dickinson3c286e22014-04-05 09:29:00 +0100464 a._denominator ** power,
465 _normalize=False)
Mark Dickinson84479652016-08-22 10:50:53 +0100466 elif a._numerator >= 0:
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000467 return Fraction(a._denominator ** -power,
Mark Dickinson3c286e22014-04-05 09:29:00 +0100468 a._numerator ** -power,
469 _normalize=False)
Mark Dickinson84479652016-08-22 10:50:53 +0100470 else:
471 return Fraction((-a._denominator) ** -power,
472 (-a._numerator) ** -power,
473 _normalize=False)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000474 else:
475 # A fractional power will generally produce an
476 # irrational number.
477 return float(a) ** float(b)
478 else:
479 return float(a) ** b
480
481 def __rpow__(b, a):
482 """a ** b"""
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000483 if b._denominator == 1 and b._numerator >= 0:
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000484 # If a is an int, keep it that way if possible.
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000485 return a ** b._numerator
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000486
Christian Heimes3feef612008-02-11 06:19:17 +0000487 if isinstance(a, numbers.Rational):
488 return Fraction(a.numerator, a.denominator) ** b
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000489
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000490 if b._denominator == 1:
491 return a ** b._numerator
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000492
493 return a ** float(b)
494
495 def __pos__(a):
Christian Heimes3feef612008-02-11 06:19:17 +0000496 """+a: Coerces a subclass instance to Fraction"""
Mark Dickinson3c286e22014-04-05 09:29:00 +0100497 return Fraction(a._numerator, a._denominator, _normalize=False)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000498
499 def __neg__(a):
500 """-a"""
Mark Dickinson3c286e22014-04-05 09:29:00 +0100501 return Fraction(-a._numerator, a._denominator, _normalize=False)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000502
503 def __abs__(a):
504 """abs(a)"""
Mark Dickinson3c286e22014-04-05 09:29:00 +0100505 return Fraction(abs(a._numerator), a._denominator, _normalize=False)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000506
507 def __trunc__(a):
508 """trunc(a)"""
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000509 if a._numerator < 0:
510 return -(-a._numerator // a._denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000511 else:
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000512 return a._numerator // a._denominator
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000513
514 def __floor__(a):
515 """Will be math.floor(a) in 3.0."""
516 return a.numerator // a.denominator
517
518 def __ceil__(a):
519 """Will be math.ceil(a) in 3.0."""
520 # The negations cleverly convince floordiv to return the ceiling.
521 return -(-a.numerator // a.denominator)
522
523 def __round__(self, ndigits=None):
524 """Will be round(self, ndigits) in 3.0.
525
526 Rounds half toward even.
527 """
528 if ndigits is None:
529 floor, remainder = divmod(self.numerator, self.denominator)
530 if remainder * 2 < self.denominator:
531 return floor
532 elif remainder * 2 > self.denominator:
533 return floor + 1
534 # Deal with the half case:
535 elif floor % 2 == 0:
536 return floor
537 else:
538 return floor + 1
539 shift = 10**abs(ndigits)
540 # See _operator_fallbacks.forward to check that the results of
Christian Heimes3feef612008-02-11 06:19:17 +0000541 # these operations will always be Fraction and therefore have
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000542 # round().
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000543 if ndigits > 0:
Christian Heimes3feef612008-02-11 06:19:17 +0000544 return Fraction(round(self * shift), shift)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000545 else:
Christian Heimes3feef612008-02-11 06:19:17 +0000546 return Fraction(round(self / shift) * shift)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000547
548 def __hash__(self):
Mark Dickinsonfec66202010-11-13 10:27:38 +0000549 """hash(self)"""
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000550
Christian Heimes969fe572008-01-25 11:23:10 +0000551 # XXX since this method is expensive, consider caching the result
Mark Dickinsondc787d22010-05-23 13:33:13 +0000552
553 # In order to make sure that the hash of a Fraction agrees
554 # with the hash of a numerically equal integer, float or
555 # Decimal instance, we follow the rules for numeric hashes
556 # outlined in the documentation. (See library docs, 'Built-in
557 # Types').
558
559 # dinv is the inverse of self._denominator modulo the prime
560 # _PyHASH_MODULUS, or 0 if self._denominator is divisible by
561 # _PyHASH_MODULUS.
562 dinv = pow(self._denominator, _PyHASH_MODULUS - 2, _PyHASH_MODULUS)
563 if not dinv:
564 hash_ = _PyHASH_INF
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000565 else:
Mark Dickinsondc787d22010-05-23 13:33:13 +0000566 hash_ = abs(self._numerator) * dinv % _PyHASH_MODULUS
Mark Dickinsonfec66202010-11-13 10:27:38 +0000567 result = hash_ if self >= 0 else -hash_
568 return -2 if result == -1 else result
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000569
570 def __eq__(a, b):
571 """a == b"""
Georg Brandl40f97352014-09-24 08:37:55 +0200572 if type(b) is int:
573 return a._numerator == b and a._denominator == 1
Christian Heimes3feef612008-02-11 06:19:17 +0000574 if isinstance(b, numbers.Rational):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000575 return (a._numerator == b.numerator and
576 a._denominator == b.denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000577 if isinstance(b, numbers.Complex) and b.imag == 0:
578 b = b.real
579 if isinstance(b, float):
Mark Dickinson85424c92009-07-18 14:41:42 +0000580 if math.isnan(b) or math.isinf(b):
581 # comparisons with an infinity or nan should behave in
582 # the same way for any finite a, so treat a as zero.
583 return 0.0 == b
584 else:
585 return a == a.from_float(b)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000586 else:
Mark Dickinson85424c92009-07-18 14:41:42 +0000587 # Since a doesn't know how to compare with b, let's give b
588 # a chance to compare itself with a.
589 return NotImplemented
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000590
Mark Dickinson85424c92009-07-18 14:41:42 +0000591 def _richcmp(self, other, op):
592 """Helper for comparison operators, for internal use only.
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000593
Mark Dickinson85424c92009-07-18 14:41:42 +0000594 Implement comparison between a Rational instance `self`, and
595 either another Rational instance or a float `other`. If
596 `other` is not a Rational instance or a float, return
597 NotImplemented. `op` should be one of the six standard
598 comparison operators.
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000599
600 """
Mark Dickinson85424c92009-07-18 14:41:42 +0000601 # convert other to a Rational instance where reasonable.
602 if isinstance(other, numbers.Rational):
603 return op(self._numerator * other.denominator,
604 self._denominator * other.numerator)
Mark Dickinson85424c92009-07-18 14:41:42 +0000605 if isinstance(other, float):
606 if math.isnan(other) or math.isinf(other):
607 return op(0.0, other)
608 else:
609 return op(self, self.from_float(other))
610 else:
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000611 return NotImplemented
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000612
613 def __lt__(a, b):
614 """a < b"""
Mark Dickinson85424c92009-07-18 14:41:42 +0000615 return a._richcmp(b, operator.lt)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000616
617 def __gt__(a, b):
618 """a > b"""
Mark Dickinson85424c92009-07-18 14:41:42 +0000619 return a._richcmp(b, operator.gt)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000620
621 def __le__(a, b):
622 """a <= b"""
Mark Dickinson85424c92009-07-18 14:41:42 +0000623 return a._richcmp(b, operator.le)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000624
625 def __ge__(a, b):
626 """a >= b"""
Mark Dickinson85424c92009-07-18 14:41:42 +0000627 return a._richcmp(b, operator.ge)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000628
629 def __bool__(a):
630 """a != 0"""
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000631 return a._numerator != 0
Christian Heimes969fe572008-01-25 11:23:10 +0000632
633 # support for pickling, copy, and deepcopy
634
635 def __reduce__(self):
636 return (self.__class__, (str(self),))
637
638 def __copy__(self):
Christian Heimes3feef612008-02-11 06:19:17 +0000639 if type(self) == Fraction:
Christian Heimes969fe572008-01-25 11:23:10 +0000640 return self # I'm immutable; therefore I am my own clone
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000641 return self.__class__(self._numerator, self._denominator)
Christian Heimes969fe572008-01-25 11:23:10 +0000642
643 def __deepcopy__(self, memo):
Christian Heimes3feef612008-02-11 06:19:17 +0000644 if type(self) == Fraction:
Christian Heimes969fe572008-01-25 11:23:10 +0000645 return self # My components are also immutable
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000646 return self.__class__(self._numerator, self._denominator)