blob: 2e7047a81844d2465d7eecbe5638ba87d17715ed [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
Raymond Hettingerf03b4c82019-08-11 14:40:59 -0700219 def as_integer_ratio(self):
220 """Return the integer ratio as a tuple.
221
222 Return a tuple of two integers, whose ratio is equal to the
223 Fraction and with a positive denominator.
224 """
225 return (self._numerator, self._denominator)
226
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000227 def limit_denominator(self, max_denominator=1000000):
228 """Closest Fraction to self with denominator at most max_denominator.
Christian Heimesbbffeb62008-01-24 09:42:52 +0000229
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000230 >>> Fraction('3.141592653589793').limit_denominator(10)
231 Fraction(22, 7)
232 >>> Fraction('3.141592653589793').limit_denominator(100)
233 Fraction(311, 99)
Mark Dickinsondfb15622009-11-23 16:27:17 +0000234 >>> Fraction(4321, 8765).limit_denominator(10000)
235 Fraction(4321, 8765)
Christian Heimesbbffeb62008-01-24 09:42:52 +0000236
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000237 """
238 # Algorithm notes: For any real number x, define a *best upper
239 # approximation* to x to be a rational number p/q such that:
240 #
241 # (1) p/q >= x, and
242 # (2) if p/q > r/s >= x then s > q, for any rational r/s.
243 #
244 # Define *best lower approximation* similarly. Then it can be
245 # proved that a rational number is a best upper or lower
246 # approximation to x if, and only if, it is a convergent or
247 # semiconvergent of the (unique shortest) continued fraction
248 # associated to x.
249 #
250 # To find a best rational approximation with denominator <= M,
251 # we find the best upper and lower approximations with
252 # denominator <= M and take whichever of these is closer to x.
253 # In the event of a tie, the bound with smaller denominator is
254 # chosen. If both denominators are equal (which can happen
255 # only when max_denominator == 1 and self is midway between
256 # two integers) the lower bound---i.e., the floor of self, is
257 # taken.
258
259 if max_denominator < 1:
260 raise ValueError("max_denominator should be at least 1")
261 if self._denominator <= max_denominator:
262 return Fraction(self)
263
264 p0, q0, p1, q1 = 0, 1, 1, 0
265 n, d = self._numerator, self._denominator
266 while True:
267 a = n//d
268 q2 = q0+a*q1
269 if q2 > max_denominator:
Christian Heimesbbffeb62008-01-24 09:42:52 +0000270 break
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000271 p0, q0, p1, q1 = p1, q1, p0+a*p1, q2
272 n, d = d, n-a*d
273
274 k = (max_denominator-q0)//q1
275 bound1 = Fraction(p0+k*p1, q0+k*q1)
276 bound2 = Fraction(p1, q1)
277 if abs(bound2 - self) <= abs(bound1-self):
278 return bound2
279 else:
280 return bound1
Christian Heimesbbffeb62008-01-24 09:42:52 +0000281
Christian Heimes400adb02008-02-01 08:12:03 +0000282 @property
283 def numerator(a):
284 return a._numerator
285
286 @property
287 def denominator(a):
288 return a._denominator
289
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000290 def __repr__(self):
291 """repr(self)"""
Serhiy Storchaka465e60e2014-07-25 23:36:00 +0300292 return '%s(%s, %s)' % (self.__class__.__name__,
293 self._numerator, self._denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000294
295 def __str__(self):
296 """str(self)"""
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000297 if self._denominator == 1:
298 return str(self._numerator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000299 else:
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000300 return '%s/%s' % (self._numerator, self._denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000301
302 def _operator_fallbacks(monomorphic_operator, fallback_operator):
303 """Generates forward and reverse operators given a purely-rational
304 operator and a function from the operator module.
305
306 Use this like:
307 __op__, __rop__ = _operator_fallbacks(just_rational_op, operator.op)
308
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000309 In general, we want to implement the arithmetic operations so
310 that mixed-mode operations either call an implementation whose
311 author knew about the types of both arguments, or convert both
312 to the nearest built in type and do the operation there. In
Christian Heimes3feef612008-02-11 06:19:17 +0000313 Fraction, that means that we define __add__ and __radd__ as:
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000314
315 def __add__(self, other):
Christian Heimes400adb02008-02-01 08:12:03 +0000316 # Both types have numerators/denominator attributes,
317 # so do the operation directly
Christian Heimes3feef612008-02-11 06:19:17 +0000318 if isinstance(other, (int, Fraction)):
319 return Fraction(self.numerator * other.denominator +
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000320 other.numerator * self.denominator,
321 self.denominator * other.denominator)
Christian Heimes400adb02008-02-01 08:12:03 +0000322 # float and complex don't have those operations, but we
323 # know about those types, so special case them.
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000324 elif isinstance(other, float):
325 return float(self) + other
326 elif isinstance(other, complex):
327 return complex(self) + other
Christian Heimes400adb02008-02-01 08:12:03 +0000328 # Let the other type take over.
329 return NotImplemented
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000330
331 def __radd__(self, other):
332 # radd handles more types than add because there's
333 # nothing left to fall back to.
Christian Heimes3feef612008-02-11 06:19:17 +0000334 if isinstance(other, numbers.Rational):
335 return Fraction(self.numerator * other.denominator +
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000336 other.numerator * self.denominator,
337 self.denominator * other.denominator)
338 elif isinstance(other, Real):
339 return float(other) + float(self)
340 elif isinstance(other, Complex):
341 return complex(other) + complex(self)
Christian Heimes400adb02008-02-01 08:12:03 +0000342 return NotImplemented
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000343
344
345 There are 5 different cases for a mixed-type addition on
Christian Heimes3feef612008-02-11 06:19:17 +0000346 Fraction. I'll refer to all of the above code that doesn't
347 refer to Fraction, float, or complex as "boilerplate". 'r'
348 will be an instance of Fraction, which is a subtype of
349 Rational (r : Fraction <: Rational), and b : B <:
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000350 Complex. The first three involve 'r + b':
351
Christian Heimes3feef612008-02-11 06:19:17 +0000352 1. If B <: Fraction, int, float, or complex, we handle
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000353 that specially, and all is well.
Christian Heimes3feef612008-02-11 06:19:17 +0000354 2. If Fraction falls back to the boilerplate code, and it
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000355 were to return a value from __add__, we'd miss the
356 possibility that B defines a more intelligent __radd__,
357 so the boilerplate should return NotImplemented from
Christian Heimes3feef612008-02-11 06:19:17 +0000358 __add__. In particular, we don't handle Rational
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000359 here, even though we could get an exact answer, in case
360 the other type wants to do something special.
Christian Heimes3feef612008-02-11 06:19:17 +0000361 3. If B <: Fraction, Python tries B.__radd__ before
362 Fraction.__add__. This is ok, because it was
363 implemented with knowledge of Fraction, so it can
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000364 handle those instances before delegating to Real or
365 Complex.
366
367 The next two situations describe 'b + r'. We assume that b
Christian Heimes3feef612008-02-11 06:19:17 +0000368 didn't know about Fraction in its implementation, and that it
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000369 uses similar boilerplate code:
370
Christian Heimes3feef612008-02-11 06:19:17 +0000371 4. If B <: Rational, then __radd_ converts both to the
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000372 builtin rational type (hey look, that's us) and
373 proceeds.
374 5. Otherwise, __radd__ tries to find the nearest common
375 base ABC, and fall back to its builtin type. Since this
376 class doesn't subclass a concrete type, there's no
377 implementation to fall back to, so we need to try as
378 hard as possible to return an actual value, or the user
379 will get a TypeError.
380
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000381 """
382 def forward(a, b):
Christian Heimes3feef612008-02-11 06:19:17 +0000383 if isinstance(b, (int, Fraction)):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000384 return monomorphic_operator(a, b)
385 elif isinstance(b, float):
386 return fallback_operator(float(a), b)
387 elif isinstance(b, complex):
388 return fallback_operator(complex(a), b)
389 else:
390 return NotImplemented
391 forward.__name__ = '__' + fallback_operator.__name__ + '__'
392 forward.__doc__ = monomorphic_operator.__doc__
393
394 def reverse(b, a):
Christian Heimes3feef612008-02-11 06:19:17 +0000395 if isinstance(a, numbers.Rational):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000396 # Includes ints.
397 return monomorphic_operator(a, b)
398 elif isinstance(a, numbers.Real):
399 return fallback_operator(float(a), float(b))
400 elif isinstance(a, numbers.Complex):
401 return fallback_operator(complex(a), complex(b))
402 else:
403 return NotImplemented
404 reverse.__name__ = '__r' + fallback_operator.__name__ + '__'
405 reverse.__doc__ = monomorphic_operator.__doc__
406
407 return forward, reverse
408
409 def _add(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 __add__, __radd__ = _operator_fallbacks(_add, operator.add)
416
417 def _sub(a, b):
418 """a - b"""
Georg Brandl40f97352014-09-24 08:37:55 +0200419 da, db = a.denominator, b.denominator
420 return Fraction(a.numerator * db - b.numerator * da,
421 da * db)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000422
423 __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub)
424
425 def _mul(a, b):
426 """a * b"""
Christian Heimes3feef612008-02-11 06:19:17 +0000427 return Fraction(a.numerator * b.numerator, a.denominator * b.denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000428
429 __mul__, __rmul__ = _operator_fallbacks(_mul, operator.mul)
430
431 def _div(a, b):
432 """a / b"""
Christian Heimes3feef612008-02-11 06:19:17 +0000433 return Fraction(a.numerator * b.denominator,
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000434 a.denominator * b.numerator)
435
436 __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000437
Elias Zamaria393f1ff2018-08-26 23:59:28 -0700438 def _floordiv(a, b):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000439 """a // b"""
Stefan Behnel3a374e02019-01-02 13:22:06 +0100440 return (a.numerator * b.denominator) // (a.denominator * b.numerator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000441
Elias Zamaria393f1ff2018-08-26 23:59:28 -0700442 __floordiv__, __rfloordiv__ = _operator_fallbacks(_floordiv, operator.floordiv)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000443
Stefan Behnel3a374e02019-01-02 13:22:06 +0100444 def _divmod(a, b):
445 """(a // b, a % b)"""
446 da, db = a.denominator, b.denominator
447 div, n_mod = divmod(a.numerator * db, da * b.numerator)
448 return div, Fraction(n_mod, da * db)
449
450 __divmod__, __rdivmod__ = _operator_fallbacks(_divmod, divmod)
451
Elias Zamaria393f1ff2018-08-26 23:59:28 -0700452 def _mod(a, b):
Christian Heimes969fe572008-01-25 11:23:10 +0000453 """a % b"""
Stefan Behnel3a374e02019-01-02 13:22:06 +0100454 da, db = a.denominator, b.denominator
455 return Fraction((a.numerator * db) % (b.numerator * da), da * db)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000456
Elias Zamaria393f1ff2018-08-26 23:59:28 -0700457 __mod__, __rmod__ = _operator_fallbacks(_mod, operator.mod)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000458
459 def __pow__(a, b):
460 """a ** b
461
462 If b is not an integer, the result will be a float or complex
463 since roots are generally irrational. If b is an integer, the
464 result will be rational.
465
466 """
Christian Heimes3feef612008-02-11 06:19:17 +0000467 if isinstance(b, numbers.Rational):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000468 if b.denominator == 1:
469 power = b.numerator
470 if power >= 0:
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000471 return Fraction(a._numerator ** power,
Mark Dickinson3c286e22014-04-05 09:29:00 +0100472 a._denominator ** power,
473 _normalize=False)
Mark Dickinson84479652016-08-22 10:50:53 +0100474 elif a._numerator >= 0:
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000475 return Fraction(a._denominator ** -power,
Mark Dickinson3c286e22014-04-05 09:29:00 +0100476 a._numerator ** -power,
477 _normalize=False)
Mark Dickinson84479652016-08-22 10:50:53 +0100478 else:
479 return Fraction((-a._denominator) ** -power,
480 (-a._numerator) ** -power,
481 _normalize=False)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000482 else:
483 # A fractional power will generally produce an
484 # irrational number.
485 return float(a) ** float(b)
486 else:
487 return float(a) ** b
488
489 def __rpow__(b, a):
490 """a ** b"""
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000491 if b._denominator == 1 and b._numerator >= 0:
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000492 # If a is an int, keep it that way if possible.
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000493 return a ** b._numerator
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000494
Christian Heimes3feef612008-02-11 06:19:17 +0000495 if isinstance(a, numbers.Rational):
496 return Fraction(a.numerator, a.denominator) ** b
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000497
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000498 if b._denominator == 1:
499 return a ** b._numerator
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000500
501 return a ** float(b)
502
503 def __pos__(a):
Christian Heimes3feef612008-02-11 06:19:17 +0000504 """+a: Coerces a subclass instance to Fraction"""
Mark Dickinson3c286e22014-04-05 09:29:00 +0100505 return Fraction(a._numerator, a._denominator, _normalize=False)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000506
507 def __neg__(a):
508 """-a"""
Mark Dickinson3c286e22014-04-05 09:29:00 +0100509 return Fraction(-a._numerator, a._denominator, _normalize=False)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000510
511 def __abs__(a):
512 """abs(a)"""
Mark Dickinson3c286e22014-04-05 09:29:00 +0100513 return Fraction(abs(a._numerator), a._denominator, _normalize=False)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000514
515 def __trunc__(a):
516 """trunc(a)"""
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000517 if a._numerator < 0:
518 return -(-a._numerator // a._denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000519 else:
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000520 return a._numerator // a._denominator
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000521
522 def __floor__(a):
Jakub Molinskia9a28802019-04-15 14:37:04 +0200523 """math.floor(a)"""
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000524 return a.numerator // a.denominator
525
526 def __ceil__(a):
Jakub Molinskia9a28802019-04-15 14:37:04 +0200527 """math.ceil(a)"""
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000528 # The negations cleverly convince floordiv to return the ceiling.
529 return -(-a.numerator // a.denominator)
530
531 def __round__(self, ndigits=None):
Jakub Molinskia9a28802019-04-15 14:37:04 +0200532 """round(self, ndigits)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000533
534 Rounds half toward even.
535 """
536 if ndigits is None:
537 floor, remainder = divmod(self.numerator, self.denominator)
538 if remainder * 2 < self.denominator:
539 return floor
540 elif remainder * 2 > self.denominator:
541 return floor + 1
542 # Deal with the half case:
543 elif floor % 2 == 0:
544 return floor
545 else:
546 return floor + 1
547 shift = 10**abs(ndigits)
548 # See _operator_fallbacks.forward to check that the results of
Christian Heimes3feef612008-02-11 06:19:17 +0000549 # these operations will always be Fraction and therefore have
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000550 # round().
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000551 if ndigits > 0:
Christian Heimes3feef612008-02-11 06:19:17 +0000552 return Fraction(round(self * shift), shift)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000553 else:
Christian Heimes3feef612008-02-11 06:19:17 +0000554 return Fraction(round(self / shift) * shift)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000555
556 def __hash__(self):
Mark Dickinsonfec66202010-11-13 10:27:38 +0000557 """hash(self)"""
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000558
Raymond Hettingerf3cb68f2019-08-15 20:58:26 -0700559 # To make sure that the hash of a Fraction agrees with the hash
560 # of a numerically equal integer, float or Decimal instance, we
561 # follow the rules for numeric hashes outlined in the
562 # documentation. (See library docs, 'Built-in Types').
Mark Dickinsondc787d22010-05-23 13:33:13 +0000563
Raymond Hettingerf3cb68f2019-08-15 20:58:26 -0700564 try:
565 dinv = pow(self._denominator, -1, _PyHASH_MODULUS)
566 except ValueError:
Tim Peters29bb2272019-08-16 21:09:16 -0500567 # ValueError means there is no modular inverse.
Mark Dickinsondc787d22010-05-23 13:33:13 +0000568 hash_ = _PyHASH_INF
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000569 else:
Tim Peters29bb2272019-08-16 21:09:16 -0500570 # The general algorithm now specifies that the absolute value of
571 # the hash is
572 # (|N| * dinv) % P
573 # where N is self._numerator and P is _PyHASH_MODULUS. That's
574 # optimized here in two ways: first, for a non-negative int i,
575 # hash(i) == i % P, but the int hash implementation doesn't need
576 # to divide, and is faster than doing % P explicitly. So we do
577 # hash(|N| * dinv)
578 # instead. Second, N is unbounded, so its product with dinv may
579 # be arbitrarily expensive to compute. The final answer is the
580 # same if we use the bounded |N| % P instead, which can again
581 # be done with an int hash() call. If 0 <= i < P, hash(i) == i,
582 # so this nested hash() call wastes a bit of time making a
583 # redundant copy when |N| < P, but can save an arbitrarily large
584 # amount of computation for large |N|.
585 hash_ = hash(hash(abs(self._numerator)) * dinv)
Raymond Hettingerf3cb68f2019-08-15 20:58:26 -0700586 result = hash_ if self._numerator >= 0 else -hash_
Mark Dickinsonfec66202010-11-13 10:27:38 +0000587 return -2 if result == -1 else result
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000588
589 def __eq__(a, b):
590 """a == b"""
Georg Brandl40f97352014-09-24 08:37:55 +0200591 if type(b) is int:
592 return a._numerator == b and a._denominator == 1
Christian Heimes3feef612008-02-11 06:19:17 +0000593 if isinstance(b, numbers.Rational):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000594 return (a._numerator == b.numerator and
595 a._denominator == b.denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000596 if isinstance(b, numbers.Complex) and b.imag == 0:
597 b = b.real
598 if isinstance(b, float):
Mark Dickinson85424c92009-07-18 14:41:42 +0000599 if math.isnan(b) or math.isinf(b):
600 # comparisons with an infinity or nan should behave in
601 # the same way for any finite a, so treat a as zero.
602 return 0.0 == b
603 else:
604 return a == a.from_float(b)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000605 else:
Mark Dickinson85424c92009-07-18 14:41:42 +0000606 # Since a doesn't know how to compare with b, let's give b
607 # a chance to compare itself with a.
608 return NotImplemented
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000609
Mark Dickinson85424c92009-07-18 14:41:42 +0000610 def _richcmp(self, other, op):
611 """Helper for comparison operators, for internal use only.
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000612
Mark Dickinson85424c92009-07-18 14:41:42 +0000613 Implement comparison between a Rational instance `self`, and
614 either another Rational instance or a float `other`. If
615 `other` is not a Rational instance or a float, return
616 NotImplemented. `op` should be one of the six standard
617 comparison operators.
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000618
619 """
Mark Dickinson85424c92009-07-18 14:41:42 +0000620 # convert other to a Rational instance where reasonable.
621 if isinstance(other, numbers.Rational):
622 return op(self._numerator * other.denominator,
623 self._denominator * other.numerator)
Mark Dickinson85424c92009-07-18 14:41:42 +0000624 if isinstance(other, float):
625 if math.isnan(other) or math.isinf(other):
626 return op(0.0, other)
627 else:
628 return op(self, self.from_float(other))
629 else:
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000630 return NotImplemented
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000631
632 def __lt__(a, b):
633 """a < b"""
Mark Dickinson85424c92009-07-18 14:41:42 +0000634 return a._richcmp(b, operator.lt)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000635
636 def __gt__(a, b):
637 """a > b"""
Mark Dickinson85424c92009-07-18 14:41:42 +0000638 return a._richcmp(b, operator.gt)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000639
640 def __le__(a, b):
641 """a <= b"""
Mark Dickinson85424c92009-07-18 14:41:42 +0000642 return a._richcmp(b, operator.le)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000643
644 def __ge__(a, b):
645 """a >= b"""
Mark Dickinson85424c92009-07-18 14:41:42 +0000646 return a._richcmp(b, operator.ge)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000647
648 def __bool__(a):
649 """a != 0"""
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000650 return a._numerator != 0
Christian Heimes969fe572008-01-25 11:23:10 +0000651
652 # support for pickling, copy, and deepcopy
653
654 def __reduce__(self):
655 return (self.__class__, (str(self),))
656
657 def __copy__(self):
Christian Heimes3feef612008-02-11 06:19:17 +0000658 if type(self) == Fraction:
Christian Heimes969fe572008-01-25 11:23:10 +0000659 return self # I'm immutable; therefore I am my own clone
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000660 return self.__class__(self._numerator, self._denominator)
Christian Heimes969fe572008-01-25 11:23:10 +0000661
662 def __deepcopy__(self, memo):
Christian Heimes3feef612008-02-11 06:19:17 +0000663 if type(self) == Fraction:
Christian Heimes969fe572008-01-25 11:23:10 +0000664 return self # My components are also immutable
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000665 return self.__class__(self._numerator, self._denominator)