blob: de3e23b759227c3bc03cc299f272b12c513399cc [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
Victor Stinner4691a2f2020-01-16 11:02:51 +010013__all__ = ['Fraction']
Guido van Rossum7736b5b2008-01-15 21:44:53 +000014
Guido van Rossum7736b5b2008-01-15 21:44:53 +000015
Mark Dickinsondc787d22010-05-23 13:33:13 +000016# Constants related to the hash implementation; hash(x) is based
17# on the reduction of x modulo the prime _PyHASH_MODULUS.
18_PyHASH_MODULUS = sys.hash_info.modulus
19# Value to be used for rationals that reduce to infinity modulo
20# _PyHASH_MODULUS.
21_PyHASH_INF = sys.hash_info.inf
Guido van Rossum7736b5b2008-01-15 21:44:53 +000022
Christian Heimes292d3512008-02-03 16:51:08 +000023_RATIONAL_FORMAT = re.compile(r"""
24 \A\s* # optional whitespace at the start, then
25 (?P<sign>[-+]?) # an optional sign, then
26 (?=\d|\.\d) # lookahead for digit or .digit
27 (?P<num>\d*) # numerator (possibly empty)
Mark Dickinsoncf63f2f2009-04-22 17:50:21 +000028 (?: # followed by
29 (?:/(?P<denom>\d+))? # an optional denominator
Christian Heimes292d3512008-02-03 16:51:08 +000030 | # or
Mark Dickinsoncf63f2f2009-04-22 17:50:21 +000031 (?:\.(?P<decimal>\d*))? # an optional fractional part
32 (?:E(?P<exp>[-+]?\d+))? # and optional exponent
33 )
Christian Heimes292d3512008-02-03 16:51:08 +000034 \s*\Z # and optional whitespace to finish
Mark Dickinsoncf63f2f2009-04-22 17:50:21 +000035""", re.VERBOSE | re.IGNORECASE)
Christian Heimes587c2bf2008-01-19 16:21:02 +000036
37
Christian Heimes3feef612008-02-11 06:19:17 +000038class Fraction(numbers.Rational):
Guido van Rossum7736b5b2008-01-15 21:44:53 +000039 """This class implements rational numbers.
40
Mark Dickinson98127c32010-04-03 11:18:52 +000041 In the two-argument form of the constructor, Fraction(8, 6) will
42 produce a rational number equivalent to 4/3. Both arguments must
43 be Rational. The numerator defaults to 0 and the denominator
44 defaults to 1 so that Fraction(3) == 3 and Fraction() == 0.
Guido van Rossum7736b5b2008-01-15 21:44:53 +000045
Mark Dickinson98127c32010-04-03 11:18:52 +000046 Fractions can also be constructed from:
47
48 - numeric strings similar to those accepted by the
49 float constructor (for example, '-2.3' or '1e10')
50
51 - strings of the form '123/456'
52
53 - float and Decimal instances
54
55 - other Rational instances (including integers)
Christian Heimes587c2bf2008-01-19 16:21:02 +000056
Guido van Rossum7736b5b2008-01-15 21:44:53 +000057 """
58
Christian Heimes400adb02008-02-01 08:12:03 +000059 __slots__ = ('_numerator', '_denominator')
Guido van Rossum7736b5b2008-01-15 21:44:53 +000060
Christian Heimes587c2bf2008-01-19 16:21:02 +000061 # We're immutable, so use __new__ not __init__
Mark Dickinson7caf9082016-08-23 16:16:52 +010062 def __new__(cls, numerator=0, denominator=None, *, _normalize=True):
Christian Heimes587c2bf2008-01-19 16:21:02 +000063 """Constructs a Rational.
64
Mark Dickinson98127c32010-04-03 11:18:52 +000065 Takes a string like '3/2' or '1.5', another Rational instance, a
66 numerator/denominator pair, or a float.
67
68 Examples
69 --------
70
71 >>> Fraction(10, -8)
72 Fraction(-5, 4)
73 >>> Fraction(Fraction(1, 7), 5)
74 Fraction(1, 35)
75 >>> Fraction(Fraction(1, 7), Fraction(2, 3))
76 Fraction(3, 14)
77 >>> Fraction('314')
78 Fraction(314, 1)
79 >>> Fraction('-35/4')
80 Fraction(-35, 4)
81 >>> Fraction('3.1415') # conversion from numeric string
82 Fraction(6283, 2000)
83 >>> Fraction('-47e-2') # string may include a decimal exponent
84 Fraction(-47, 100)
85 >>> Fraction(1.47) # direct construction from float (exact conversion)
86 Fraction(6620291452234629, 4503599627370496)
87 >>> Fraction(2.25)
88 Fraction(9, 4)
89 >>> Fraction(Decimal('1.47'))
90 Fraction(147, 100)
Christian Heimes587c2bf2008-01-19 16:21:02 +000091
92 """
Christian Heimes3feef612008-02-11 06:19:17 +000093 self = super(Fraction, cls).__new__(cls)
Christian Heimes587c2bf2008-01-19 16:21:02 +000094
Mark Dickinsond4d95f82009-04-24 14:06:19 +000095 if denominator is None:
Georg Brandl40f97352014-09-24 08:37:55 +020096 if type(numerator) is int:
97 self._numerator = numerator
98 self._denominator = 1
99 return self
100
101 elif isinstance(numerator, numbers.Rational):
Mark Dickinsond4d95f82009-04-24 14:06:19 +0000102 self._numerator = numerator.numerator
103 self._denominator = numerator.denominator
104 return self
105
Serhiy Storchaka0d250bc2015-12-29 22:34:23 +0200106 elif isinstance(numerator, (float, Decimal)):
107 # Exact conversion
108 self._numerator, self._denominator = numerator.as_integer_ratio()
Mark Dickinson98127c32010-04-03 11:18:52 +0000109 return self
110
Mark Dickinsond4d95f82009-04-24 14:06:19 +0000111 elif isinstance(numerator, str):
Christian Heimes587c2bf2008-01-19 16:21:02 +0000112 # Handle construction from strings.
Mark Dickinsoncf63f2f2009-04-22 17:50:21 +0000113 m = _RATIONAL_FORMAT.match(numerator)
Christian Heimes587c2bf2008-01-19 16:21:02 +0000114 if m is None:
Mark Dickinsoncf63f2f2009-04-22 17:50:21 +0000115 raise ValueError('Invalid literal for Fraction: %r' %
116 numerator)
117 numerator = int(m.group('num') or '0')
118 denom = m.group('denom')
119 if denom:
120 denominator = int(denom)
Christian Heimesaf98da12008-01-27 15:18:18 +0000121 else:
Mark Dickinsoncf63f2f2009-04-22 17:50:21 +0000122 denominator = 1
123 decimal = m.group('decimal')
124 if decimal:
125 scale = 10**len(decimal)
126 numerator = numerator * scale + int(decimal)
127 denominator *= scale
128 exp = m.group('exp')
129 if exp:
130 exp = int(exp)
131 if exp >= 0:
132 numerator *= 10**exp
133 else:
134 denominator *= 10**-exp
Christian Heimes587c2bf2008-01-19 16:21:02 +0000135 if m.group('sign') == '-':
136 numerator = -numerator
137
Mark Dickinsond4d95f82009-04-24 14:06:19 +0000138 else:
139 raise TypeError("argument should be a string "
140 "or a Rational instance")
141
Georg Brandl40f97352014-09-24 08:37:55 +0200142 elif type(numerator) is int is type(denominator):
Serhiy Storchaka48e47aa2015-05-13 00:19:51 +0300143 pass # *very* normal case
Georg Brandl40f97352014-09-24 08:37:55 +0200144
Mark Dickinsond4d95f82009-04-24 14:06:19 +0000145 elif (isinstance(numerator, numbers.Rational) and
146 isinstance(denominator, numbers.Rational)):
147 numerator, denominator = (
148 numerator.numerator * denominator.denominator,
149 denominator.numerator * numerator.denominator
150 )
151 else:
152 raise TypeError("both arguments should be "
153 "Rational instances")
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000154
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000155 if denominator == 0:
Christian Heimes3feef612008-02-11 06:19:17 +0000156 raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
Mark Dickinson3c286e22014-04-05 09:29:00 +0100157 if _normalize:
Victor Stinnerdc7a50d2020-02-07 23:42:51 +0100158 g = math.gcd(numerator, denominator)
159 if denominator < 0:
160 g = -g
Mark Dickinson3c286e22014-04-05 09:29:00 +0100161 numerator //= g
162 denominator //= g
163 self._numerator = numerator
164 self._denominator = denominator
Christian Heimes587c2bf2008-01-19 16:21:02 +0000165 return self
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000166
167 @classmethod
168 def from_float(cls, f):
Christian Heimes587c2bf2008-01-19 16:21:02 +0000169 """Converts a finite float to a rational number, exactly.
170
Christian Heimes3feef612008-02-11 06:19:17 +0000171 Beware that Fraction.from_float(0.3) != Fraction(3, 10).
Christian Heimes587c2bf2008-01-19 16:21:02 +0000172
173 """
Georg Brandl2ee470f2008-07-16 12:55:28 +0000174 if isinstance(f, numbers.Integral):
Georg Brandl3a9b0622009-01-03 22:07:57 +0000175 return cls(f)
Georg Brandl2ee470f2008-07-16 12:55:28 +0000176 elif not isinstance(f, float):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000177 raise TypeError("%s.from_float() only takes floats, not %r (%s)" %
178 (cls.__name__, f, type(f).__name__))
Christian Heimes26855632008-01-27 23:50:43 +0000179 return cls(*f.as_integer_ratio())
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000180
Christian Heimes587c2bf2008-01-19 16:21:02 +0000181 @classmethod
182 def from_decimal(cls, dec):
183 """Converts a finite Decimal instance to a rational number, exactly."""
184 from decimal import Decimal
Georg Brandl2ee470f2008-07-16 12:55:28 +0000185 if isinstance(dec, numbers.Integral):
186 dec = Decimal(int(dec))
187 elif not isinstance(dec, Decimal):
Christian Heimes587c2bf2008-01-19 16:21:02 +0000188 raise TypeError(
189 "%s.from_decimal() only takes Decimals, not %r (%s)" %
190 (cls.__name__, dec, type(dec).__name__))
Serhiy Storchaka0d250bc2015-12-29 22:34:23 +0200191 return cls(*dec.as_integer_ratio())
Christian Heimes587c2bf2008-01-19 16:21:02 +0000192
Raymond Hettingerf03b4c82019-08-11 14:40:59 -0700193 def as_integer_ratio(self):
194 """Return the integer ratio as a tuple.
195
196 Return a tuple of two integers, whose ratio is equal to the
197 Fraction and with a positive denominator.
198 """
199 return (self._numerator, self._denominator)
200
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000201 def limit_denominator(self, max_denominator=1000000):
202 """Closest Fraction to self with denominator at most max_denominator.
Christian Heimesbbffeb62008-01-24 09:42:52 +0000203
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000204 >>> Fraction('3.141592653589793').limit_denominator(10)
205 Fraction(22, 7)
206 >>> Fraction('3.141592653589793').limit_denominator(100)
207 Fraction(311, 99)
Mark Dickinsondfb15622009-11-23 16:27:17 +0000208 >>> Fraction(4321, 8765).limit_denominator(10000)
209 Fraction(4321, 8765)
Christian Heimesbbffeb62008-01-24 09:42:52 +0000210
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000211 """
212 # Algorithm notes: For any real number x, define a *best upper
213 # approximation* to x to be a rational number p/q such that:
214 #
215 # (1) p/q >= x, and
216 # (2) if p/q > r/s >= x then s > q, for any rational r/s.
217 #
218 # Define *best lower approximation* similarly. Then it can be
219 # proved that a rational number is a best upper or lower
220 # approximation to x if, and only if, it is a convergent or
221 # semiconvergent of the (unique shortest) continued fraction
222 # associated to x.
223 #
224 # To find a best rational approximation with denominator <= M,
225 # we find the best upper and lower approximations with
226 # denominator <= M and take whichever of these is closer to x.
227 # In the event of a tie, the bound with smaller denominator is
228 # chosen. If both denominators are equal (which can happen
229 # only when max_denominator == 1 and self is midway between
230 # two integers) the lower bound---i.e., the floor of self, is
231 # taken.
232
233 if max_denominator < 1:
234 raise ValueError("max_denominator should be at least 1")
235 if self._denominator <= max_denominator:
236 return Fraction(self)
237
238 p0, q0, p1, q1 = 0, 1, 1, 0
239 n, d = self._numerator, self._denominator
240 while True:
241 a = n//d
242 q2 = q0+a*q1
243 if q2 > max_denominator:
Christian Heimesbbffeb62008-01-24 09:42:52 +0000244 break
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000245 p0, q0, p1, q1 = p1, q1, p0+a*p1, q2
246 n, d = d, n-a*d
247
248 k = (max_denominator-q0)//q1
249 bound1 = Fraction(p0+k*p1, q0+k*q1)
250 bound2 = Fraction(p1, q1)
251 if abs(bound2 - self) <= abs(bound1-self):
252 return bound2
253 else:
254 return bound1
Christian Heimesbbffeb62008-01-24 09:42:52 +0000255
Christian Heimes400adb02008-02-01 08:12:03 +0000256 @property
257 def numerator(a):
258 return a._numerator
259
260 @property
261 def denominator(a):
262 return a._denominator
263
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000264 def __repr__(self):
265 """repr(self)"""
Serhiy Storchaka465e60e2014-07-25 23:36:00 +0300266 return '%s(%s, %s)' % (self.__class__.__name__,
267 self._numerator, self._denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000268
269 def __str__(self):
270 """str(self)"""
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000271 if self._denominator == 1:
272 return str(self._numerator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000273 else:
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000274 return '%s/%s' % (self._numerator, self._denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000275
276 def _operator_fallbacks(monomorphic_operator, fallback_operator):
277 """Generates forward and reverse operators given a purely-rational
278 operator and a function from the operator module.
279
280 Use this like:
281 __op__, __rop__ = _operator_fallbacks(just_rational_op, operator.op)
282
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000283 In general, we want to implement the arithmetic operations so
284 that mixed-mode operations either call an implementation whose
285 author knew about the types of both arguments, or convert both
286 to the nearest built in type and do the operation there. In
Christian Heimes3feef612008-02-11 06:19:17 +0000287 Fraction, that means that we define __add__ and __radd__ as:
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000288
289 def __add__(self, other):
Christian Heimes400adb02008-02-01 08:12:03 +0000290 # Both types have numerators/denominator attributes,
291 # so do the operation directly
Christian Heimes3feef612008-02-11 06:19:17 +0000292 if isinstance(other, (int, Fraction)):
293 return Fraction(self.numerator * other.denominator +
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000294 other.numerator * self.denominator,
295 self.denominator * other.denominator)
Christian Heimes400adb02008-02-01 08:12:03 +0000296 # float and complex don't have those operations, but we
297 # know about those types, so special case them.
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000298 elif isinstance(other, float):
299 return float(self) + other
300 elif isinstance(other, complex):
301 return complex(self) + other
Christian Heimes400adb02008-02-01 08:12:03 +0000302 # Let the other type take over.
303 return NotImplemented
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000304
305 def __radd__(self, other):
306 # radd handles more types than add because there's
307 # nothing left to fall back to.
Christian Heimes3feef612008-02-11 06:19:17 +0000308 if isinstance(other, numbers.Rational):
309 return Fraction(self.numerator * other.denominator +
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000310 other.numerator * self.denominator,
311 self.denominator * other.denominator)
312 elif isinstance(other, Real):
313 return float(other) + float(self)
314 elif isinstance(other, Complex):
315 return complex(other) + complex(self)
Christian Heimes400adb02008-02-01 08:12:03 +0000316 return NotImplemented
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000317
318
319 There are 5 different cases for a mixed-type addition on
Christian Heimes3feef612008-02-11 06:19:17 +0000320 Fraction. I'll refer to all of the above code that doesn't
321 refer to Fraction, float, or complex as "boilerplate". 'r'
322 will be an instance of Fraction, which is a subtype of
323 Rational (r : Fraction <: Rational), and b : B <:
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000324 Complex. The first three involve 'r + b':
325
Christian Heimes3feef612008-02-11 06:19:17 +0000326 1. If B <: Fraction, int, float, or complex, we handle
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000327 that specially, and all is well.
Christian Heimes3feef612008-02-11 06:19:17 +0000328 2. If Fraction falls back to the boilerplate code, and it
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000329 were to return a value from __add__, we'd miss the
330 possibility that B defines a more intelligent __radd__,
331 so the boilerplate should return NotImplemented from
Christian Heimes3feef612008-02-11 06:19:17 +0000332 __add__. In particular, we don't handle Rational
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000333 here, even though we could get an exact answer, in case
334 the other type wants to do something special.
Christian Heimes3feef612008-02-11 06:19:17 +0000335 3. If B <: Fraction, Python tries B.__radd__ before
336 Fraction.__add__. This is ok, because it was
337 implemented with knowledge of Fraction, so it can
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000338 handle those instances before delegating to Real or
339 Complex.
340
341 The next two situations describe 'b + r'. We assume that b
Christian Heimes3feef612008-02-11 06:19:17 +0000342 didn't know about Fraction in its implementation, and that it
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000343 uses similar boilerplate code:
344
Christian Heimes3feef612008-02-11 06:19:17 +0000345 4. If B <: Rational, then __radd_ converts both to the
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000346 builtin rational type (hey look, that's us) and
347 proceeds.
348 5. Otherwise, __radd__ tries to find the nearest common
349 base ABC, and fall back to its builtin type. Since this
350 class doesn't subclass a concrete type, there's no
351 implementation to fall back to, so we need to try as
352 hard as possible to return an actual value, or the user
353 will get a TypeError.
354
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000355 """
356 def forward(a, b):
Christian Heimes3feef612008-02-11 06:19:17 +0000357 if isinstance(b, (int, Fraction)):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000358 return monomorphic_operator(a, b)
359 elif isinstance(b, float):
360 return fallback_operator(float(a), b)
361 elif isinstance(b, complex):
362 return fallback_operator(complex(a), b)
363 else:
364 return NotImplemented
365 forward.__name__ = '__' + fallback_operator.__name__ + '__'
366 forward.__doc__ = monomorphic_operator.__doc__
367
368 def reverse(b, a):
Christian Heimes3feef612008-02-11 06:19:17 +0000369 if isinstance(a, numbers.Rational):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000370 # Includes ints.
371 return monomorphic_operator(a, b)
372 elif isinstance(a, numbers.Real):
373 return fallback_operator(float(a), float(b))
374 elif isinstance(a, numbers.Complex):
375 return fallback_operator(complex(a), complex(b))
376 else:
377 return NotImplemented
378 reverse.__name__ = '__r' + fallback_operator.__name__ + '__'
379 reverse.__doc__ = monomorphic_operator.__doc__
380
381 return forward, reverse
382
383 def _add(a, b):
384 """a + b"""
Georg Brandl40f97352014-09-24 08:37:55 +0200385 da, db = a.denominator, b.denominator
386 return Fraction(a.numerator * db + b.numerator * da,
387 da * db)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000388
389 __add__, __radd__ = _operator_fallbacks(_add, operator.add)
390
391 def _sub(a, b):
392 """a - b"""
Georg Brandl40f97352014-09-24 08:37:55 +0200393 da, db = a.denominator, b.denominator
394 return Fraction(a.numerator * db - b.numerator * da,
395 da * db)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000396
397 __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub)
398
399 def _mul(a, b):
400 """a * b"""
Christian Heimes3feef612008-02-11 06:19:17 +0000401 return Fraction(a.numerator * b.numerator, a.denominator * b.denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000402
403 __mul__, __rmul__ = _operator_fallbacks(_mul, operator.mul)
404
405 def _div(a, b):
406 """a / b"""
Christian Heimes3feef612008-02-11 06:19:17 +0000407 return Fraction(a.numerator * b.denominator,
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000408 a.denominator * b.numerator)
409
410 __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000411
Elias Zamaria393f1ff2018-08-26 23:59:28 -0700412 def _floordiv(a, b):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000413 """a // b"""
Stefan Behnel3a374e02019-01-02 13:22:06 +0100414 return (a.numerator * b.denominator) // (a.denominator * b.numerator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000415
Elias Zamaria393f1ff2018-08-26 23:59:28 -0700416 __floordiv__, __rfloordiv__ = _operator_fallbacks(_floordiv, operator.floordiv)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000417
Stefan Behnel3a374e02019-01-02 13:22:06 +0100418 def _divmod(a, b):
419 """(a // b, a % b)"""
420 da, db = a.denominator, b.denominator
421 div, n_mod = divmod(a.numerator * db, da * b.numerator)
422 return div, Fraction(n_mod, da * db)
423
424 __divmod__, __rdivmod__ = _operator_fallbacks(_divmod, divmod)
425
Elias Zamaria393f1ff2018-08-26 23:59:28 -0700426 def _mod(a, b):
Christian Heimes969fe572008-01-25 11:23:10 +0000427 """a % b"""
Stefan Behnel3a374e02019-01-02 13:22:06 +0100428 da, db = a.denominator, b.denominator
429 return Fraction((a.numerator * db) % (b.numerator * da), da * db)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000430
Elias Zamaria393f1ff2018-08-26 23:59:28 -0700431 __mod__, __rmod__ = _operator_fallbacks(_mod, operator.mod)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000432
433 def __pow__(a, b):
434 """a ** b
435
436 If b is not an integer, the result will be a float or complex
437 since roots are generally irrational. If b is an integer, the
438 result will be rational.
439
440 """
Christian Heimes3feef612008-02-11 06:19:17 +0000441 if isinstance(b, numbers.Rational):
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000442 if b.denominator == 1:
443 power = b.numerator
444 if power >= 0:
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000445 return Fraction(a._numerator ** power,
Mark Dickinson3c286e22014-04-05 09:29:00 +0100446 a._denominator ** power,
447 _normalize=False)
Mark Dickinson84479652016-08-22 10:50:53 +0100448 elif a._numerator >= 0:
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000449 return Fraction(a._denominator ** -power,
Mark Dickinson3c286e22014-04-05 09:29:00 +0100450 a._numerator ** -power,
451 _normalize=False)
Mark Dickinson84479652016-08-22 10:50:53 +0100452 else:
453 return Fraction((-a._denominator) ** -power,
454 (-a._numerator) ** -power,
455 _normalize=False)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000456 else:
457 # A fractional power will generally produce an
458 # irrational number.
459 return float(a) ** float(b)
460 else:
461 return float(a) ** b
462
463 def __rpow__(b, a):
464 """a ** b"""
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000465 if b._denominator == 1 and b._numerator >= 0:
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000466 # If a is an int, keep it that way if possible.
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000467 return a ** b._numerator
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000468
Christian Heimes3feef612008-02-11 06:19:17 +0000469 if isinstance(a, numbers.Rational):
470 return Fraction(a.numerator, a.denominator) ** b
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000471
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000472 if b._denominator == 1:
473 return a ** b._numerator
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000474
475 return a ** float(b)
476
477 def __pos__(a):
Christian Heimes3feef612008-02-11 06:19:17 +0000478 """+a: Coerces a subclass instance to Fraction"""
Mark Dickinson3c286e22014-04-05 09:29:00 +0100479 return Fraction(a._numerator, a._denominator, _normalize=False)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000480
481 def __neg__(a):
482 """-a"""
Mark Dickinson3c286e22014-04-05 09:29:00 +0100483 return Fraction(-a._numerator, a._denominator, _normalize=False)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000484
485 def __abs__(a):
486 """abs(a)"""
Mark Dickinson3c286e22014-04-05 09:29:00 +0100487 return Fraction(abs(a._numerator), a._denominator, _normalize=False)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000488
489 def __trunc__(a):
490 """trunc(a)"""
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000491 if a._numerator < 0:
492 return -(-a._numerator // a._denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000493 else:
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000494 return a._numerator // a._denominator
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000495
496 def __floor__(a):
Jakub Molinskia9a28802019-04-15 14:37:04 +0200497 """math.floor(a)"""
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000498 return a.numerator // a.denominator
499
500 def __ceil__(a):
Jakub Molinskia9a28802019-04-15 14:37:04 +0200501 """math.ceil(a)"""
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000502 # The negations cleverly convince floordiv to return the ceiling.
503 return -(-a.numerator // a.denominator)
504
505 def __round__(self, ndigits=None):
Jakub Molinskia9a28802019-04-15 14:37:04 +0200506 """round(self, ndigits)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000507
508 Rounds half toward even.
509 """
510 if ndigits is None:
511 floor, remainder = divmod(self.numerator, self.denominator)
512 if remainder * 2 < self.denominator:
513 return floor
514 elif remainder * 2 > self.denominator:
515 return floor + 1
516 # Deal with the half case:
517 elif floor % 2 == 0:
518 return floor
519 else:
520 return floor + 1
521 shift = 10**abs(ndigits)
522 # See _operator_fallbacks.forward to check that the results of
Christian Heimes3feef612008-02-11 06:19:17 +0000523 # these operations will always be Fraction and therefore have
Jeffrey Yasskin9893de12008-01-17 07:36:30 +0000524 # round().
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000525 if ndigits > 0:
Christian Heimes3feef612008-02-11 06:19:17 +0000526 return Fraction(round(self * shift), shift)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000527 else:
Christian Heimes3feef612008-02-11 06:19:17 +0000528 return Fraction(round(self / shift) * shift)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000529
530 def __hash__(self):
Mark Dickinsonfec66202010-11-13 10:27:38 +0000531 """hash(self)"""
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000532
Raymond Hettingerf3cb68f2019-08-15 20:58:26 -0700533 # To make sure that the hash of a Fraction agrees with the hash
534 # of a numerically equal integer, float or Decimal instance, we
535 # follow the rules for numeric hashes outlined in the
536 # documentation. (See library docs, 'Built-in Types').
Mark Dickinsondc787d22010-05-23 13:33:13 +0000537
Raymond Hettingerf3cb68f2019-08-15 20:58:26 -0700538 try:
539 dinv = pow(self._denominator, -1, _PyHASH_MODULUS)
540 except ValueError:
Tim Peters29bb2272019-08-16 21:09:16 -0500541 # ValueError means there is no modular inverse.
Mark Dickinsondc787d22010-05-23 13:33:13 +0000542 hash_ = _PyHASH_INF
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000543 else:
Tim Peters29bb2272019-08-16 21:09:16 -0500544 # The general algorithm now specifies that the absolute value of
545 # the hash is
546 # (|N| * dinv) % P
547 # where N is self._numerator and P is _PyHASH_MODULUS. That's
548 # optimized here in two ways: first, for a non-negative int i,
549 # hash(i) == i % P, but the int hash implementation doesn't need
550 # to divide, and is faster than doing % P explicitly. So we do
551 # hash(|N| * dinv)
552 # instead. Second, N is unbounded, so its product with dinv may
553 # be arbitrarily expensive to compute. The final answer is the
554 # same if we use the bounded |N| % P instead, which can again
555 # be done with an int hash() call. If 0 <= i < P, hash(i) == i,
556 # so this nested hash() call wastes a bit of time making a
557 # redundant copy when |N| < P, but can save an arbitrarily large
558 # amount of computation for large |N|.
559 hash_ = hash(hash(abs(self._numerator)) * dinv)
Raymond Hettingerf3cb68f2019-08-15 20:58:26 -0700560 result = hash_ if self._numerator >= 0 else -hash_
Mark Dickinsonfec66202010-11-13 10:27:38 +0000561 return -2 if result == -1 else result
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000562
563 def __eq__(a, b):
564 """a == b"""
Georg Brandl40f97352014-09-24 08:37:55 +0200565 if type(b) is int:
566 return a._numerator == b and a._denominator == 1
Christian Heimes3feef612008-02-11 06:19:17 +0000567 if isinstance(b, numbers.Rational):
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000568 return (a._numerator == b.numerator and
569 a._denominator == b.denominator)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000570 if isinstance(b, numbers.Complex) and b.imag == 0:
571 b = b.real
572 if isinstance(b, float):
Mark Dickinson85424c92009-07-18 14:41:42 +0000573 if math.isnan(b) or math.isinf(b):
574 # comparisons with an infinity or nan should behave in
575 # the same way for any finite a, so treat a as zero.
576 return 0.0 == b
577 else:
578 return a == a.from_float(b)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000579 else:
Mark Dickinson85424c92009-07-18 14:41:42 +0000580 # Since a doesn't know how to compare with b, let's give b
581 # a chance to compare itself with a.
582 return NotImplemented
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000583
Mark Dickinson85424c92009-07-18 14:41:42 +0000584 def _richcmp(self, other, op):
585 """Helper for comparison operators, for internal use only.
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000586
Mark Dickinson85424c92009-07-18 14:41:42 +0000587 Implement comparison between a Rational instance `self`, and
588 either another Rational instance or a float `other`. If
589 `other` is not a Rational instance or a float, return
590 NotImplemented. `op` should be one of the six standard
591 comparison operators.
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000592
593 """
Mark Dickinson85424c92009-07-18 14:41:42 +0000594 # convert other to a Rational instance where reasonable.
595 if isinstance(other, numbers.Rational):
596 return op(self._numerator * other.denominator,
597 self._denominator * other.numerator)
Mark Dickinson85424c92009-07-18 14:41:42 +0000598 if isinstance(other, float):
599 if math.isnan(other) or math.isinf(other):
600 return op(0.0, other)
601 else:
602 return op(self, self.from_float(other))
603 else:
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000604 return NotImplemented
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000605
606 def __lt__(a, b):
607 """a < b"""
Mark Dickinson85424c92009-07-18 14:41:42 +0000608 return a._richcmp(b, operator.lt)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000609
610 def __gt__(a, b):
611 """a > b"""
Mark Dickinson85424c92009-07-18 14:41:42 +0000612 return a._richcmp(b, operator.gt)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000613
614 def __le__(a, b):
615 """a <= b"""
Mark Dickinson85424c92009-07-18 14:41:42 +0000616 return a._richcmp(b, operator.le)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000617
618 def __ge__(a, b):
619 """a >= b"""
Mark Dickinson85424c92009-07-18 14:41:42 +0000620 return a._richcmp(b, operator.ge)
Guido van Rossum7736b5b2008-01-15 21:44:53 +0000621
622 def __bool__(a):
623 """a != 0"""
Sebastian Berg427c84f2020-02-06 06:54:05 -0800624 # bpo-39274: Use bool() because (a._numerator != 0) can return an
625 # object which is not a bool.
626 return bool(a._numerator)
Christian Heimes969fe572008-01-25 11:23:10 +0000627
628 # support for pickling, copy, and deepcopy
629
630 def __reduce__(self):
631 return (self.__class__, (str(self),))
632
633 def __copy__(self):
Christian Heimes3feef612008-02-11 06:19:17 +0000634 if type(self) == Fraction:
Christian Heimes969fe572008-01-25 11:23:10 +0000635 return self # I'm immutable; therefore I am my own clone
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000636 return self.__class__(self._numerator, self._denominator)
Christian Heimes969fe572008-01-25 11:23:10 +0000637
638 def __deepcopy__(self, memo):
Christian Heimes3feef612008-02-11 06:19:17 +0000639 if type(self) == Fraction:
Christian Heimes969fe572008-01-25 11:23:10 +0000640 return self # My components are also immutable
Christian Heimes68f5fbe2008-02-14 08:27:37 +0000641 return self.__class__(self._numerator, self._denominator)