1# Originally contributed by Sjoerd Mullender.
2# Significantly modified by Jeffrey Yasskin <jyasskin at gmail.com>.
3
4"""Fraction, infinite-precision, real numbers."""
5
6from decimal import Decimal
7import math
8import numbers
9import operator
10import re
11import sys
12
13__all__ = ['Fraction', 'gcd']
14
15
16
17def gcd(a, b):
18    """Calculate the Greatest Common Divisor of a and b.
19
20    Unless b==0, the result will have the same sign as b (so that when
21    b is divided by it, the result comes out positive).
22    """
23    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.
34    while b:
35        a, b = b, a%b
36    return a
37
38# 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
44
45_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)
50    (?:                        # followed by
51       (?:/(?P<denom>\d+))?    # an optional denominator
52    |                          # or
53       (?:\.(?P<decimal>\d*))? # an optional fractional part
54       (?:E(?P<exp>[-+]?\d+))? # and optional exponent
55    )
56    \s*\Z                      # and optional whitespace to finish
57""", re.VERBOSE | re.IGNORECASE)
58
59
60class Fraction(numbers.Rational):
61    """This class implements rational numbers.
62
63    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.
67
68    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)
78
79    """
80
81    __slots__ = ('_numerator', '_denominator')
82
83    # We're immutable, so use __new__ not __init__
84    def __new__(cls, numerator=0, denominator=None, *, _normalize=True):
85        """Constructs a Rational.
86
87        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)
113
114        """
115        self = super(Fraction, cls).__new__(cls)
116
117        if denominator is None:
118            if type(numerator) is int:
119                self._numerator = numerator
120                self._denominator = 1
121                return self
122
123            elif isinstance(numerator, numbers.Rational):
124                self._numerator = numerator.numerator
125                self._denominator = numerator.denominator
126                return self
127
128            elif isinstance(numerator, (float, Decimal)):
129                # Exact conversion
130                self._numerator, self._denominator = numerator.as_integer_ratio()
131                return self
132
133            elif isinstance(numerator, str):
134                # Handle construction from strings.
135                m = _RATIONAL_FORMAT.match(numerator)
136                if m is None:
137                    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)
143                else:
144                    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
157                if m.group('sign') == '-':
158                    numerator = -numerator
159
160            else:
161                raise TypeError("argument should be a string "
162                                "or a Rational instance")
163
164        elif type(numerator) is int is type(denominator):
165            pass # *very* normal case
166
167        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")
176
177        if denominator == 0:
178            raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
179        if _normalize:
180            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)
187            numerator //= g
188            denominator //= g
189        self._numerator = numerator
190        self._denominator = denominator
191        return self
192
193    @classmethod
194    def from_float(cls, f):
195        """Converts a finite float to a rational number, exactly.
196
197        Beware that Fraction.from_float(0.3) != Fraction(3, 10).
198
199        """
200        if isinstance(f, numbers.Integral):
201            return cls(f)
202        elif not isinstance(f, float):
203            raise TypeError("%s.from_float() only takes floats, not %r (%s)" %
204                            (cls.__name__, f, type(f).__name__))
205        return cls(*f.as_integer_ratio())
206
207    @classmethod
208    def from_decimal(cls, dec):
209        """Converts a finite Decimal instance to a rational number, exactly."""
210        from decimal import Decimal
211        if isinstance(dec, numbers.Integral):
212            dec = Decimal(int(dec))
213        elif not isinstance(dec, Decimal):
214            raise TypeError(
215                "%s.from_decimal() only takes Decimals, not %r (%s)" %
216                (cls.__name__, dec, type(dec).__name__))
217        return cls(*dec.as_integer_ratio())
218
219    def limit_denominator(self, max_denominator=1000000):
220        """Closest Fraction to self with denominator at most max_denominator.
221
222        >>> Fraction('3.141592653589793').limit_denominator(10)
223        Fraction(22, 7)
224        >>> Fraction('3.141592653589793').limit_denominator(100)
225        Fraction(311, 99)
226        >>> Fraction(4321, 8765).limit_denominator(10000)
227        Fraction(4321, 8765)
228
229        """
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:
262                break
263            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
273
274    @property
275    def numerator(a):
276        return a._numerator
277
278    @property
279    def denominator(a):
280        return a._denominator
281
282    def __repr__(self):
283        """repr(self)"""
284        return '%s(%s, %s)' % (self.__class__.__name__,
285                               self._numerator, self._denominator)
286
287    def __str__(self):
288        """str(self)"""
289        if self._denominator == 1:
290            return str(self._numerator)
291        else:
292            return '%s/%s' % (self._numerator, self._denominator)
293
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
301        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
305        Fraction, that means that we define __add__ and __radd__ as:
306
307            def __add__(self, other):
308                # Both types have numerators/denominator attributes,
309                # so do the operation directly
310                if isinstance(other, (int, Fraction)):
311                    return Fraction(self.numerator * other.denominator +
312                                    other.numerator * self.denominator,
313                                    self.denominator * other.denominator)
314                # float and complex don't have those operations, but we
315                # know about those types, so special case them.
316                elif isinstance(other, float):
317                    return float(self) + other
318                elif isinstance(other, complex):
319                    return complex(self) + other
320                # Let the other type take over.
321                return NotImplemented
322
323            def __radd__(self, other):
324                # radd handles more types than add because there's
325                # nothing left to fall back to.
326                if isinstance(other, numbers.Rational):
327                    return Fraction(self.numerator * other.denominator +
328                                    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)
334                return NotImplemented
335
336
337        There are 5 different cases for a mixed-type addition on
338        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 <:
342        Complex. The first three involve 'r + b':
343
344            1. If B <: Fraction, int, float, or complex, we handle
345               that specially, and all is well.
346            2. If Fraction falls back to the boilerplate code, and it
347               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
350               __add__. In particular, we don't handle Rational
351               here, even though we could get an exact answer, in case
352               the other type wants to do something special.
353            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
356               handle those instances before delegating to Real or
357               Complex.
358
359        The next two situations describe 'b + r'. We assume that b
360        didn't know about Fraction in its implementation, and that it
361        uses similar boilerplate code:
362
363            4. If B <: Rational, then __radd_ converts both to the
364               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
373        """
374        def forward(a, b):
375            if isinstance(b, (int, Fraction)):
376                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):
387            if isinstance(a, numbers.Rational):
388                # 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"""
403        da, db = a.denominator, b.denominator
404        return Fraction(a.numerator * db + b.numerator * da,
405                        da * db)
406
407    __add__, __radd__ = _operator_fallbacks(_add, operator.add)
408
409    def _sub(a, b):
410        """a - b"""
411        da, db = a.denominator, b.denominator
412        return Fraction(a.numerator * db - b.numerator * da,
413                        da * db)
414
415    __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub)
416
417    def _mul(a, b):
418        """a * b"""
419        return Fraction(a.numerator * b.numerator, a.denominator * b.denominator)
420
421    __mul__, __rmul__ = _operator_fallbacks(_mul, operator.mul)
422
423    def _div(a, b):
424        """a / b"""
425        return Fraction(a.numerator * b.denominator,
426                        a.denominator * b.numerator)
427
428    __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv)
429
430    def __floordiv__(a, b):
431        """a // b"""
432        return math.floor(a / b)
433
434    def __rfloordiv__(b, a):
435        """a // b"""
436        return math.floor(a / b)
437
438    def __mod__(a, b):
439        """a % b"""
440        div = a // b
441        return a - b * div
442
443    def __rmod__(b, a):
444        """a % b"""
445        div = a // b
446        return a - b * div
447
448    def __pow__(a, b):
449        """a ** b
450
451        If b is not an integer, the result will be a float or complex
452        since roots are generally irrational. If b is an integer, the
453        result will be rational.
454
455        """
456        if isinstance(b, numbers.Rational):
457            if b.denominator == 1:
458                power = b.numerator
459                if power >= 0:
460                    return Fraction(a._numerator ** power,
461                                    a._denominator ** power,
462                                    _normalize=False)
463                elif a._numerator >= 0:
464                    return Fraction(a._denominator ** -power,
465                                    a._numerator ** -power,
466                                    _normalize=False)
467                else:
468                    return Fraction((-a._denominator) ** -power,
469                                    (-a._numerator) ** -power,
470                                    _normalize=False)
471            else:
472                # A fractional power will generally produce an
473                # irrational number.
474                return float(a) ** float(b)
475        else:
476            return float(a) ** b
477
478    def __rpow__(b, a):
479        """a ** b"""
480        if b._denominator == 1 and b._numerator >= 0:
481            # If a is an int, keep it that way if possible.
482            return a ** b._numerator
483
484        if isinstance(a, numbers.Rational):
485            return Fraction(a.numerator, a.denominator) ** b
486
487        if b._denominator == 1:
488            return a ** b._numerator
489
490        return a ** float(b)
491
492    def __pos__(a):
493        """+a: Coerces a subclass instance to Fraction"""
494        return Fraction(a._numerator, a._denominator, _normalize=False)
495
496    def __neg__(a):
497        """-a"""
498        return Fraction(-a._numerator, a._denominator, _normalize=False)
499
500    def __abs__(a):
501        """abs(a)"""
502        return Fraction(abs(a._numerator), a._denominator, _normalize=False)
503
504    def __trunc__(a):
505        """trunc(a)"""
506        if a._numerator < 0:
507            return -(-a._numerator // a._denominator)
508        else:
509            return a._numerator // a._denominator
510
511    def __floor__(a):
512        """Will be math.floor(a) in 3.0."""
513        return a.numerator // a.denominator
514
515    def __ceil__(a):
516        """Will be math.ceil(a) in 3.0."""
517        # The negations cleverly convince floordiv to return the ceiling.
518        return -(-a.numerator // a.denominator)
519
520    def __round__(self, ndigits=None):
521        """Will be round(self, ndigits) in 3.0.
522
523        Rounds half toward even.
524        """
525        if ndigits is None:
526            floor, remainder = divmod(self.numerator, self.denominator)
527            if remainder * 2 < self.denominator:
528                return floor
529            elif remainder * 2 > self.denominator:
530                return floor + 1
531            # Deal with the half case:
532            elif floor % 2 == 0:
533                return floor
534            else:
535                return floor + 1
536        shift = 10**abs(ndigits)
537        # See _operator_fallbacks.forward to check that the results of
538        # these operations will always be Fraction and therefore have
539        # round().
540        if ndigits > 0:
541            return Fraction(round(self * shift), shift)
542        else:
543            return Fraction(round(self / shift) * shift)
544
545    def __hash__(self):
546        """hash(self)"""
547
548        # XXX since this method is expensive, consider caching the result
549
550        # In order to make sure that the hash of a Fraction agrees
551        # with the hash of a numerically equal integer, float or
552        # Decimal instance, we follow the rules for numeric hashes
553        # outlined in the documentation.  (See library docs, 'Built-in
554        # Types').
555
556        # dinv is the inverse of self._denominator modulo the prime
557        # _PyHASH_MODULUS, or 0 if self._denominator is divisible by
558        # _PyHASH_MODULUS.
559        dinv = pow(self._denominator, _PyHASH_MODULUS - 2, _PyHASH_MODULUS)
560        if not dinv:
561            hash_ = _PyHASH_INF
562        else:
563            hash_ = abs(self._numerator) * dinv % _PyHASH_MODULUS
564        result = hash_ if self >= 0 else -hash_
565        return -2 if result == -1 else result
566
567    def __eq__(a, b):
568        """a == b"""
569        if type(b) is int:
570            return a._numerator == b and a._denominator == 1
571        if isinstance(b, numbers.Rational):
572            return (a._numerator == b.numerator and
573                    a._denominator == b.denominator)
574        if isinstance(b, numbers.Complex) and b.imag == 0:
575            b = b.real
576        if isinstance(b, float):
577            if math.isnan(b) or math.isinf(b):
578                # comparisons with an infinity or nan should behave in
579                # the same way for any finite a, so treat a as zero.
580                return 0.0 == b
581            else:
582                return a == a.from_float(b)
583        else:
584            # Since a doesn't know how to compare with b, let's give b
585            # a chance to compare itself with a.
586            return NotImplemented
587
588    def _richcmp(self, other, op):
589        """Helper for comparison operators, for internal use only.
590
591        Implement comparison between a Rational instance `self`, and
592        either another Rational instance or a float `other`.  If
593        `other` is not a Rational instance or a float, return
594        NotImplemented. `op` should be one of the six standard
595        comparison operators.
596
597        """
598        # convert other to a Rational instance where reasonable.
599        if isinstance(other, numbers.Rational):
600            return op(self._numerator * other.denominator,
601                      self._denominator * other.numerator)
602        if isinstance(other, float):
603            if math.isnan(other) or math.isinf(other):
604                return op(0.0, other)
605            else:
606                return op(self, self.from_float(other))
607        else:
608            return NotImplemented
609
610    def __lt__(a, b):
611        """a < b"""
612        return a._richcmp(b, operator.lt)
613
614    def __gt__(a, b):
615        """a > b"""
616        return a._richcmp(b, operator.gt)
617
618    def __le__(a, b):
619        """a <= b"""
620        return a._richcmp(b, operator.le)
621
622    def __ge__(a, b):
623        """a >= b"""
624        return a._richcmp(b, operator.ge)
625
626    def __bool__(a):
627        """a != 0"""
628        return a._numerator != 0
629
630    # support for pickling, copy, and deepcopy
631
632    def __reduce__(self):
633        return (self.__class__, (str(self),))
634
635    def __copy__(self):
636        if type(self) == Fraction:
637            return self     # I'm immutable; therefore I am my own clone
638        return self.__class__(self._numerator, self._denominator)
639
640    def __deepcopy__(self, memo):
641        if type(self) == Fraction:
642            return self     # My components are also immutable
643        return self.__class__(self._numerator, self._denominator)
644