xref: /aosp_15_r20/prebuilts/build-tools/common/py3-stdlib/fractions.py (revision cda5da8d549138a6648c5ee6d7a49cf8f4a657be)
1*cda5da8dSAndroid Build Coastguard Worker# Originally contributed by Sjoerd Mullender.
2*cda5da8dSAndroid Build Coastguard Worker# Significantly modified by Jeffrey Yasskin <jyasskin at gmail.com>.
3*cda5da8dSAndroid Build Coastguard Worker
4*cda5da8dSAndroid Build Coastguard Worker"""Fraction, infinite-precision, rational numbers."""
5*cda5da8dSAndroid Build Coastguard Worker
6*cda5da8dSAndroid Build Coastguard Workerfrom decimal import Decimal
7*cda5da8dSAndroid Build Coastguard Workerimport math
8*cda5da8dSAndroid Build Coastguard Workerimport numbers
9*cda5da8dSAndroid Build Coastguard Workerimport operator
10*cda5da8dSAndroid Build Coastguard Workerimport re
11*cda5da8dSAndroid Build Coastguard Workerimport sys
12*cda5da8dSAndroid Build Coastguard Worker
13*cda5da8dSAndroid Build Coastguard Worker__all__ = ['Fraction']
14*cda5da8dSAndroid Build Coastguard Worker
15*cda5da8dSAndroid Build Coastguard Worker
16*cda5da8dSAndroid Build Coastguard Worker# Constants related to the hash implementation;  hash(x) is based
17*cda5da8dSAndroid Build Coastguard Worker# on the reduction of x modulo the prime _PyHASH_MODULUS.
18*cda5da8dSAndroid Build Coastguard Worker_PyHASH_MODULUS = sys.hash_info.modulus
19*cda5da8dSAndroid Build Coastguard Worker# Value to be used for rationals that reduce to infinity modulo
20*cda5da8dSAndroid Build Coastguard Worker# _PyHASH_MODULUS.
21*cda5da8dSAndroid Build Coastguard Worker_PyHASH_INF = sys.hash_info.inf
22*cda5da8dSAndroid Build Coastguard Worker
23*cda5da8dSAndroid Build Coastguard Worker_RATIONAL_FORMAT = re.compile(r"""
24*cda5da8dSAndroid Build Coastguard Worker    \A\s*                                 # optional whitespace at the start,
25*cda5da8dSAndroid Build Coastguard Worker    (?P<sign>[-+]?)                       # an optional sign, then
26*cda5da8dSAndroid Build Coastguard Worker    (?=\d|\.\d)                           # lookahead for digit or .digit
27*cda5da8dSAndroid Build Coastguard Worker    (?P<num>\d*|\d+(_\d+)*)               # numerator (possibly empty)
28*cda5da8dSAndroid Build Coastguard Worker    (?:                                   # followed by
29*cda5da8dSAndroid Build Coastguard Worker       (?:/(?P<denom>\d+(_\d+)*))?        # an optional denominator
30*cda5da8dSAndroid Build Coastguard Worker    |                                     # or
31*cda5da8dSAndroid Build Coastguard Worker       (?:\.(?P<decimal>d*|\d+(_\d+)*))?  # an optional fractional part
32*cda5da8dSAndroid Build Coastguard Worker       (?:E(?P<exp>[-+]?\d+(_\d+)*))?     # and optional exponent
33*cda5da8dSAndroid Build Coastguard Worker    )
34*cda5da8dSAndroid Build Coastguard Worker    \s*\Z                                 # and optional whitespace to finish
35*cda5da8dSAndroid Build Coastguard Worker""", re.VERBOSE | re.IGNORECASE)
36*cda5da8dSAndroid Build Coastguard Worker
37*cda5da8dSAndroid Build Coastguard Worker
38*cda5da8dSAndroid Build Coastguard Workerclass Fraction(numbers.Rational):
39*cda5da8dSAndroid Build Coastguard Worker    """This class implements rational numbers.
40*cda5da8dSAndroid Build Coastguard Worker
41*cda5da8dSAndroid Build Coastguard Worker    In the two-argument form of the constructor, Fraction(8, 6) will
42*cda5da8dSAndroid Build Coastguard Worker    produce a rational number equivalent to 4/3. Both arguments must
43*cda5da8dSAndroid Build Coastguard Worker    be Rational. The numerator defaults to 0 and the denominator
44*cda5da8dSAndroid Build Coastguard Worker    defaults to 1 so that Fraction(3) == 3 and Fraction() == 0.
45*cda5da8dSAndroid Build Coastguard Worker
46*cda5da8dSAndroid Build Coastguard Worker    Fractions can also be constructed from:
47*cda5da8dSAndroid Build Coastguard Worker
48*cda5da8dSAndroid Build Coastguard Worker      - numeric strings similar to those accepted by the
49*cda5da8dSAndroid Build Coastguard Worker        float constructor (for example, '-2.3' or '1e10')
50*cda5da8dSAndroid Build Coastguard Worker
51*cda5da8dSAndroid Build Coastguard Worker      - strings of the form '123/456'
52*cda5da8dSAndroid Build Coastguard Worker
53*cda5da8dSAndroid Build Coastguard Worker      - float and Decimal instances
54*cda5da8dSAndroid Build Coastguard Worker
55*cda5da8dSAndroid Build Coastguard Worker      - other Rational instances (including integers)
56*cda5da8dSAndroid Build Coastguard Worker
57*cda5da8dSAndroid Build Coastguard Worker    """
58*cda5da8dSAndroid Build Coastguard Worker
59*cda5da8dSAndroid Build Coastguard Worker    __slots__ = ('_numerator', '_denominator')
60*cda5da8dSAndroid Build Coastguard Worker
61*cda5da8dSAndroid Build Coastguard Worker    # We're immutable, so use __new__ not __init__
62*cda5da8dSAndroid Build Coastguard Worker    def __new__(cls, numerator=0, denominator=None, *, _normalize=True):
63*cda5da8dSAndroid Build Coastguard Worker        """Constructs a Rational.
64*cda5da8dSAndroid Build Coastguard Worker
65*cda5da8dSAndroid Build Coastguard Worker        Takes a string like '3/2' or '1.5', another Rational instance, a
66*cda5da8dSAndroid Build Coastguard Worker        numerator/denominator pair, or a float.
67*cda5da8dSAndroid Build Coastguard Worker
68*cda5da8dSAndroid Build Coastguard Worker        Examples
69*cda5da8dSAndroid Build Coastguard Worker        --------
70*cda5da8dSAndroid Build Coastguard Worker
71*cda5da8dSAndroid Build Coastguard Worker        >>> Fraction(10, -8)
72*cda5da8dSAndroid Build Coastguard Worker        Fraction(-5, 4)
73*cda5da8dSAndroid Build Coastguard Worker        >>> Fraction(Fraction(1, 7), 5)
74*cda5da8dSAndroid Build Coastguard Worker        Fraction(1, 35)
75*cda5da8dSAndroid Build Coastguard Worker        >>> Fraction(Fraction(1, 7), Fraction(2, 3))
76*cda5da8dSAndroid Build Coastguard Worker        Fraction(3, 14)
77*cda5da8dSAndroid Build Coastguard Worker        >>> Fraction('314')
78*cda5da8dSAndroid Build Coastguard Worker        Fraction(314, 1)
79*cda5da8dSAndroid Build Coastguard Worker        >>> Fraction('-35/4')
80*cda5da8dSAndroid Build Coastguard Worker        Fraction(-35, 4)
81*cda5da8dSAndroid Build Coastguard Worker        >>> Fraction('3.1415') # conversion from numeric string
82*cda5da8dSAndroid Build Coastguard Worker        Fraction(6283, 2000)
83*cda5da8dSAndroid Build Coastguard Worker        >>> Fraction('-47e-2') # string may include a decimal exponent
84*cda5da8dSAndroid Build Coastguard Worker        Fraction(-47, 100)
85*cda5da8dSAndroid Build Coastguard Worker        >>> Fraction(1.47)  # direct construction from float (exact conversion)
86*cda5da8dSAndroid Build Coastguard Worker        Fraction(6620291452234629, 4503599627370496)
87*cda5da8dSAndroid Build Coastguard Worker        >>> Fraction(2.25)
88*cda5da8dSAndroid Build Coastguard Worker        Fraction(9, 4)
89*cda5da8dSAndroid Build Coastguard Worker        >>> Fraction(Decimal('1.47'))
90*cda5da8dSAndroid Build Coastguard Worker        Fraction(147, 100)
91*cda5da8dSAndroid Build Coastguard Worker
92*cda5da8dSAndroid Build Coastguard Worker        """
93*cda5da8dSAndroid Build Coastguard Worker        self = super(Fraction, cls).__new__(cls)
94*cda5da8dSAndroid Build Coastguard Worker
95*cda5da8dSAndroid Build Coastguard Worker        if denominator is None:
96*cda5da8dSAndroid Build Coastguard Worker            if type(numerator) is int:
97*cda5da8dSAndroid Build Coastguard Worker                self._numerator = numerator
98*cda5da8dSAndroid Build Coastguard Worker                self._denominator = 1
99*cda5da8dSAndroid Build Coastguard Worker                return self
100*cda5da8dSAndroid Build Coastguard Worker
101*cda5da8dSAndroid Build Coastguard Worker            elif isinstance(numerator, numbers.Rational):
102*cda5da8dSAndroid Build Coastguard Worker                self._numerator = numerator.numerator
103*cda5da8dSAndroid Build Coastguard Worker                self._denominator = numerator.denominator
104*cda5da8dSAndroid Build Coastguard Worker                return self
105*cda5da8dSAndroid Build Coastguard Worker
106*cda5da8dSAndroid Build Coastguard Worker            elif isinstance(numerator, (float, Decimal)):
107*cda5da8dSAndroid Build Coastguard Worker                # Exact conversion
108*cda5da8dSAndroid Build Coastguard Worker                self._numerator, self._denominator = numerator.as_integer_ratio()
109*cda5da8dSAndroid Build Coastguard Worker                return self
110*cda5da8dSAndroid Build Coastguard Worker
111*cda5da8dSAndroid Build Coastguard Worker            elif isinstance(numerator, str):
112*cda5da8dSAndroid Build Coastguard Worker                # Handle construction from strings.
113*cda5da8dSAndroid Build Coastguard Worker                m = _RATIONAL_FORMAT.match(numerator)
114*cda5da8dSAndroid Build Coastguard Worker                if m is None:
115*cda5da8dSAndroid Build Coastguard Worker                    raise ValueError('Invalid literal for Fraction: %r' %
116*cda5da8dSAndroid Build Coastguard Worker                                     numerator)
117*cda5da8dSAndroid Build Coastguard Worker                numerator = int(m.group('num') or '0')
118*cda5da8dSAndroid Build Coastguard Worker                denom = m.group('denom')
119*cda5da8dSAndroid Build Coastguard Worker                if denom:
120*cda5da8dSAndroid Build Coastguard Worker                    denominator = int(denom)
121*cda5da8dSAndroid Build Coastguard Worker                else:
122*cda5da8dSAndroid Build Coastguard Worker                    denominator = 1
123*cda5da8dSAndroid Build Coastguard Worker                    decimal = m.group('decimal')
124*cda5da8dSAndroid Build Coastguard Worker                    if decimal:
125*cda5da8dSAndroid Build Coastguard Worker                        decimal = decimal.replace('_', '')
126*cda5da8dSAndroid Build Coastguard Worker                        scale = 10**len(decimal)
127*cda5da8dSAndroid Build Coastguard Worker                        numerator = numerator * scale + int(decimal)
128*cda5da8dSAndroid Build Coastguard Worker                        denominator *= scale
129*cda5da8dSAndroid Build Coastguard Worker                    exp = m.group('exp')
130*cda5da8dSAndroid Build Coastguard Worker                    if exp:
131*cda5da8dSAndroid Build Coastguard Worker                        exp = int(exp)
132*cda5da8dSAndroid Build Coastguard Worker                        if exp >= 0:
133*cda5da8dSAndroid Build Coastguard Worker                            numerator *= 10**exp
134*cda5da8dSAndroid Build Coastguard Worker                        else:
135*cda5da8dSAndroid Build Coastguard Worker                            denominator *= 10**-exp
136*cda5da8dSAndroid Build Coastguard Worker                if m.group('sign') == '-':
137*cda5da8dSAndroid Build Coastguard Worker                    numerator = -numerator
138*cda5da8dSAndroid Build Coastguard Worker
139*cda5da8dSAndroid Build Coastguard Worker            else:
140*cda5da8dSAndroid Build Coastguard Worker                raise TypeError("argument should be a string "
141*cda5da8dSAndroid Build Coastguard Worker                                "or a Rational instance")
142*cda5da8dSAndroid Build Coastguard Worker
143*cda5da8dSAndroid Build Coastguard Worker        elif type(numerator) is int is type(denominator):
144*cda5da8dSAndroid Build Coastguard Worker            pass # *very* normal case
145*cda5da8dSAndroid Build Coastguard Worker
146*cda5da8dSAndroid Build Coastguard Worker        elif (isinstance(numerator, numbers.Rational) and
147*cda5da8dSAndroid Build Coastguard Worker            isinstance(denominator, numbers.Rational)):
148*cda5da8dSAndroid Build Coastguard Worker            numerator, denominator = (
149*cda5da8dSAndroid Build Coastguard Worker                numerator.numerator * denominator.denominator,
150*cda5da8dSAndroid Build Coastguard Worker                denominator.numerator * numerator.denominator
151*cda5da8dSAndroid Build Coastguard Worker                )
152*cda5da8dSAndroid Build Coastguard Worker        else:
153*cda5da8dSAndroid Build Coastguard Worker            raise TypeError("both arguments should be "
154*cda5da8dSAndroid Build Coastguard Worker                            "Rational instances")
155*cda5da8dSAndroid Build Coastguard Worker
156*cda5da8dSAndroid Build Coastguard Worker        if denominator == 0:
157*cda5da8dSAndroid Build Coastguard Worker            raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
158*cda5da8dSAndroid Build Coastguard Worker        if _normalize:
159*cda5da8dSAndroid Build Coastguard Worker            g = math.gcd(numerator, denominator)
160*cda5da8dSAndroid Build Coastguard Worker            if denominator < 0:
161*cda5da8dSAndroid Build Coastguard Worker                g = -g
162*cda5da8dSAndroid Build Coastguard Worker            numerator //= g
163*cda5da8dSAndroid Build Coastguard Worker            denominator //= g
164*cda5da8dSAndroid Build Coastguard Worker        self._numerator = numerator
165*cda5da8dSAndroid Build Coastguard Worker        self._denominator = denominator
166*cda5da8dSAndroid Build Coastguard Worker        return self
167*cda5da8dSAndroid Build Coastguard Worker
168*cda5da8dSAndroid Build Coastguard Worker    @classmethod
169*cda5da8dSAndroid Build Coastguard Worker    def from_float(cls, f):
170*cda5da8dSAndroid Build Coastguard Worker        """Converts a finite float to a rational number, exactly.
171*cda5da8dSAndroid Build Coastguard Worker
172*cda5da8dSAndroid Build Coastguard Worker        Beware that Fraction.from_float(0.3) != Fraction(3, 10).
173*cda5da8dSAndroid Build Coastguard Worker
174*cda5da8dSAndroid Build Coastguard Worker        """
175*cda5da8dSAndroid Build Coastguard Worker        if isinstance(f, numbers.Integral):
176*cda5da8dSAndroid Build Coastguard Worker            return cls(f)
177*cda5da8dSAndroid Build Coastguard Worker        elif not isinstance(f, float):
178*cda5da8dSAndroid Build Coastguard Worker            raise TypeError("%s.from_float() only takes floats, not %r (%s)" %
179*cda5da8dSAndroid Build Coastguard Worker                            (cls.__name__, f, type(f).__name__))
180*cda5da8dSAndroid Build Coastguard Worker        return cls(*f.as_integer_ratio())
181*cda5da8dSAndroid Build Coastguard Worker
182*cda5da8dSAndroid Build Coastguard Worker    @classmethod
183*cda5da8dSAndroid Build Coastguard Worker    def from_decimal(cls, dec):
184*cda5da8dSAndroid Build Coastguard Worker        """Converts a finite Decimal instance to a rational number, exactly."""
185*cda5da8dSAndroid Build Coastguard Worker        from decimal import Decimal
186*cda5da8dSAndroid Build Coastguard Worker        if isinstance(dec, numbers.Integral):
187*cda5da8dSAndroid Build Coastguard Worker            dec = Decimal(int(dec))
188*cda5da8dSAndroid Build Coastguard Worker        elif not isinstance(dec, Decimal):
189*cda5da8dSAndroid Build Coastguard Worker            raise TypeError(
190*cda5da8dSAndroid Build Coastguard Worker                "%s.from_decimal() only takes Decimals, not %r (%s)" %
191*cda5da8dSAndroid Build Coastguard Worker                (cls.__name__, dec, type(dec).__name__))
192*cda5da8dSAndroid Build Coastguard Worker        return cls(*dec.as_integer_ratio())
193*cda5da8dSAndroid Build Coastguard Worker
194*cda5da8dSAndroid Build Coastguard Worker    def as_integer_ratio(self):
195*cda5da8dSAndroid Build Coastguard Worker        """Return the integer ratio as a tuple.
196*cda5da8dSAndroid Build Coastguard Worker
197*cda5da8dSAndroid Build Coastguard Worker        Return a tuple of two integers, whose ratio is equal to the
198*cda5da8dSAndroid Build Coastguard Worker        Fraction and with a positive denominator.
199*cda5da8dSAndroid Build Coastguard Worker        """
200*cda5da8dSAndroid Build Coastguard Worker        return (self._numerator, self._denominator)
201*cda5da8dSAndroid Build Coastguard Worker
202*cda5da8dSAndroid Build Coastguard Worker    def limit_denominator(self, max_denominator=1000000):
203*cda5da8dSAndroid Build Coastguard Worker        """Closest Fraction to self with denominator at most max_denominator.
204*cda5da8dSAndroid Build Coastguard Worker
205*cda5da8dSAndroid Build Coastguard Worker        >>> Fraction('3.141592653589793').limit_denominator(10)
206*cda5da8dSAndroid Build Coastguard Worker        Fraction(22, 7)
207*cda5da8dSAndroid Build Coastguard Worker        >>> Fraction('3.141592653589793').limit_denominator(100)
208*cda5da8dSAndroid Build Coastguard Worker        Fraction(311, 99)
209*cda5da8dSAndroid Build Coastguard Worker        >>> Fraction(4321, 8765).limit_denominator(10000)
210*cda5da8dSAndroid Build Coastguard Worker        Fraction(4321, 8765)
211*cda5da8dSAndroid Build Coastguard Worker
212*cda5da8dSAndroid Build Coastguard Worker        """
213*cda5da8dSAndroid Build Coastguard Worker        # Algorithm notes: For any real number x, define a *best upper
214*cda5da8dSAndroid Build Coastguard Worker        # approximation* to x to be a rational number p/q such that:
215*cda5da8dSAndroid Build Coastguard Worker        #
216*cda5da8dSAndroid Build Coastguard Worker        #   (1) p/q >= x, and
217*cda5da8dSAndroid Build Coastguard Worker        #   (2) if p/q > r/s >= x then s > q, for any rational r/s.
218*cda5da8dSAndroid Build Coastguard Worker        #
219*cda5da8dSAndroid Build Coastguard Worker        # Define *best lower approximation* similarly.  Then it can be
220*cda5da8dSAndroid Build Coastguard Worker        # proved that a rational number is a best upper or lower
221*cda5da8dSAndroid Build Coastguard Worker        # approximation to x if, and only if, it is a convergent or
222*cda5da8dSAndroid Build Coastguard Worker        # semiconvergent of the (unique shortest) continued fraction
223*cda5da8dSAndroid Build Coastguard Worker        # associated to x.
224*cda5da8dSAndroid Build Coastguard Worker        #
225*cda5da8dSAndroid Build Coastguard Worker        # To find a best rational approximation with denominator <= M,
226*cda5da8dSAndroid Build Coastguard Worker        # we find the best upper and lower approximations with
227*cda5da8dSAndroid Build Coastguard Worker        # denominator <= M and take whichever of these is closer to x.
228*cda5da8dSAndroid Build Coastguard Worker        # In the event of a tie, the bound with smaller denominator is
229*cda5da8dSAndroid Build Coastguard Worker        # chosen.  If both denominators are equal (which can happen
230*cda5da8dSAndroid Build Coastguard Worker        # only when max_denominator == 1 and self is midway between
231*cda5da8dSAndroid Build Coastguard Worker        # two integers) the lower bound---i.e., the floor of self, is
232*cda5da8dSAndroid Build Coastguard Worker        # taken.
233*cda5da8dSAndroid Build Coastguard Worker
234*cda5da8dSAndroid Build Coastguard Worker        if max_denominator < 1:
235*cda5da8dSAndroid Build Coastguard Worker            raise ValueError("max_denominator should be at least 1")
236*cda5da8dSAndroid Build Coastguard Worker        if self._denominator <= max_denominator:
237*cda5da8dSAndroid Build Coastguard Worker            return Fraction(self)
238*cda5da8dSAndroid Build Coastguard Worker
239*cda5da8dSAndroid Build Coastguard Worker        p0, q0, p1, q1 = 0, 1, 1, 0
240*cda5da8dSAndroid Build Coastguard Worker        n, d = self._numerator, self._denominator
241*cda5da8dSAndroid Build Coastguard Worker        while True:
242*cda5da8dSAndroid Build Coastguard Worker            a = n//d
243*cda5da8dSAndroid Build Coastguard Worker            q2 = q0+a*q1
244*cda5da8dSAndroid Build Coastguard Worker            if q2 > max_denominator:
245*cda5da8dSAndroid Build Coastguard Worker                break
246*cda5da8dSAndroid Build Coastguard Worker            p0, q0, p1, q1 = p1, q1, p0+a*p1, q2
247*cda5da8dSAndroid Build Coastguard Worker            n, d = d, n-a*d
248*cda5da8dSAndroid Build Coastguard Worker
249*cda5da8dSAndroid Build Coastguard Worker        k = (max_denominator-q0)//q1
250*cda5da8dSAndroid Build Coastguard Worker        bound1 = Fraction(p0+k*p1, q0+k*q1)
251*cda5da8dSAndroid Build Coastguard Worker        bound2 = Fraction(p1, q1)
252*cda5da8dSAndroid Build Coastguard Worker        if abs(bound2 - self) <= abs(bound1-self):
253*cda5da8dSAndroid Build Coastguard Worker            return bound2
254*cda5da8dSAndroid Build Coastguard Worker        else:
255*cda5da8dSAndroid Build Coastguard Worker            return bound1
256*cda5da8dSAndroid Build Coastguard Worker
257*cda5da8dSAndroid Build Coastguard Worker    @property
258*cda5da8dSAndroid Build Coastguard Worker    def numerator(a):
259*cda5da8dSAndroid Build Coastguard Worker        return a._numerator
260*cda5da8dSAndroid Build Coastguard Worker
261*cda5da8dSAndroid Build Coastguard Worker    @property
262*cda5da8dSAndroid Build Coastguard Worker    def denominator(a):
263*cda5da8dSAndroid Build Coastguard Worker        return a._denominator
264*cda5da8dSAndroid Build Coastguard Worker
265*cda5da8dSAndroid Build Coastguard Worker    def __repr__(self):
266*cda5da8dSAndroid Build Coastguard Worker        """repr(self)"""
267*cda5da8dSAndroid Build Coastguard Worker        return '%s(%s, %s)' % (self.__class__.__name__,
268*cda5da8dSAndroid Build Coastguard Worker                               self._numerator, self._denominator)
269*cda5da8dSAndroid Build Coastguard Worker
270*cda5da8dSAndroid Build Coastguard Worker    def __str__(self):
271*cda5da8dSAndroid Build Coastguard Worker        """str(self)"""
272*cda5da8dSAndroid Build Coastguard Worker        if self._denominator == 1:
273*cda5da8dSAndroid Build Coastguard Worker            return str(self._numerator)
274*cda5da8dSAndroid Build Coastguard Worker        else:
275*cda5da8dSAndroid Build Coastguard Worker            return '%s/%s' % (self._numerator, self._denominator)
276*cda5da8dSAndroid Build Coastguard Worker
277*cda5da8dSAndroid Build Coastguard Worker    def _operator_fallbacks(monomorphic_operator, fallback_operator):
278*cda5da8dSAndroid Build Coastguard Worker        """Generates forward and reverse operators given a purely-rational
279*cda5da8dSAndroid Build Coastguard Worker        operator and a function from the operator module.
280*cda5da8dSAndroid Build Coastguard Worker
281*cda5da8dSAndroid Build Coastguard Worker        Use this like:
282*cda5da8dSAndroid Build Coastguard Worker        __op__, __rop__ = _operator_fallbacks(just_rational_op, operator.op)
283*cda5da8dSAndroid Build Coastguard Worker
284*cda5da8dSAndroid Build Coastguard Worker        In general, we want to implement the arithmetic operations so
285*cda5da8dSAndroid Build Coastguard Worker        that mixed-mode operations either call an implementation whose
286*cda5da8dSAndroid Build Coastguard Worker        author knew about the types of both arguments, or convert both
287*cda5da8dSAndroid Build Coastguard Worker        to the nearest built in type and do the operation there. In
288*cda5da8dSAndroid Build Coastguard Worker        Fraction, that means that we define __add__ and __radd__ as:
289*cda5da8dSAndroid Build Coastguard Worker
290*cda5da8dSAndroid Build Coastguard Worker            def __add__(self, other):
291*cda5da8dSAndroid Build Coastguard Worker                # Both types have numerators/denominator attributes,
292*cda5da8dSAndroid Build Coastguard Worker                # so do the operation directly
293*cda5da8dSAndroid Build Coastguard Worker                if isinstance(other, (int, Fraction)):
294*cda5da8dSAndroid Build Coastguard Worker                    return Fraction(self.numerator * other.denominator +
295*cda5da8dSAndroid Build Coastguard Worker                                    other.numerator * self.denominator,
296*cda5da8dSAndroid Build Coastguard Worker                                    self.denominator * other.denominator)
297*cda5da8dSAndroid Build Coastguard Worker                # float and complex don't have those operations, but we
298*cda5da8dSAndroid Build Coastguard Worker                # know about those types, so special case them.
299*cda5da8dSAndroid Build Coastguard Worker                elif isinstance(other, float):
300*cda5da8dSAndroid Build Coastguard Worker                    return float(self) + other
301*cda5da8dSAndroid Build Coastguard Worker                elif isinstance(other, complex):
302*cda5da8dSAndroid Build Coastguard Worker                    return complex(self) + other
303*cda5da8dSAndroid Build Coastguard Worker                # Let the other type take over.
304*cda5da8dSAndroid Build Coastguard Worker                return NotImplemented
305*cda5da8dSAndroid Build Coastguard Worker
306*cda5da8dSAndroid Build Coastguard Worker            def __radd__(self, other):
307*cda5da8dSAndroid Build Coastguard Worker                # radd handles more types than add because there's
308*cda5da8dSAndroid Build Coastguard Worker                # nothing left to fall back to.
309*cda5da8dSAndroid Build Coastguard Worker                if isinstance(other, numbers.Rational):
310*cda5da8dSAndroid Build Coastguard Worker                    return Fraction(self.numerator * other.denominator +
311*cda5da8dSAndroid Build Coastguard Worker                                    other.numerator * self.denominator,
312*cda5da8dSAndroid Build Coastguard Worker                                    self.denominator * other.denominator)
313*cda5da8dSAndroid Build Coastguard Worker                elif isinstance(other, Real):
314*cda5da8dSAndroid Build Coastguard Worker                    return float(other) + float(self)
315*cda5da8dSAndroid Build Coastguard Worker                elif isinstance(other, Complex):
316*cda5da8dSAndroid Build Coastguard Worker                    return complex(other) + complex(self)
317*cda5da8dSAndroid Build Coastguard Worker                return NotImplemented
318*cda5da8dSAndroid Build Coastguard Worker
319*cda5da8dSAndroid Build Coastguard Worker
320*cda5da8dSAndroid Build Coastguard Worker        There are 5 different cases for a mixed-type addition on
321*cda5da8dSAndroid Build Coastguard Worker        Fraction. I'll refer to all of the above code that doesn't
322*cda5da8dSAndroid Build Coastguard Worker        refer to Fraction, float, or complex as "boilerplate". 'r'
323*cda5da8dSAndroid Build Coastguard Worker        will be an instance of Fraction, which is a subtype of
324*cda5da8dSAndroid Build Coastguard Worker        Rational (r : Fraction <: Rational), and b : B <:
325*cda5da8dSAndroid Build Coastguard Worker        Complex. The first three involve 'r + b':
326*cda5da8dSAndroid Build Coastguard Worker
327*cda5da8dSAndroid Build Coastguard Worker            1. If B <: Fraction, int, float, or complex, we handle
328*cda5da8dSAndroid Build Coastguard Worker               that specially, and all is well.
329*cda5da8dSAndroid Build Coastguard Worker            2. If Fraction falls back to the boilerplate code, and it
330*cda5da8dSAndroid Build Coastguard Worker               were to return a value from __add__, we'd miss the
331*cda5da8dSAndroid Build Coastguard Worker               possibility that B defines a more intelligent __radd__,
332*cda5da8dSAndroid Build Coastguard Worker               so the boilerplate should return NotImplemented from
333*cda5da8dSAndroid Build Coastguard Worker               __add__. In particular, we don't handle Rational
334*cda5da8dSAndroid Build Coastguard Worker               here, even though we could get an exact answer, in case
335*cda5da8dSAndroid Build Coastguard Worker               the other type wants to do something special.
336*cda5da8dSAndroid Build Coastguard Worker            3. If B <: Fraction, Python tries B.__radd__ before
337*cda5da8dSAndroid Build Coastguard Worker               Fraction.__add__. This is ok, because it was
338*cda5da8dSAndroid Build Coastguard Worker               implemented with knowledge of Fraction, so it can
339*cda5da8dSAndroid Build Coastguard Worker               handle those instances before delegating to Real or
340*cda5da8dSAndroid Build Coastguard Worker               Complex.
341*cda5da8dSAndroid Build Coastguard Worker
342*cda5da8dSAndroid Build Coastguard Worker        The next two situations describe 'b + r'. We assume that b
343*cda5da8dSAndroid Build Coastguard Worker        didn't know about Fraction in its implementation, and that it
344*cda5da8dSAndroid Build Coastguard Worker        uses similar boilerplate code:
345*cda5da8dSAndroid Build Coastguard Worker
346*cda5da8dSAndroid Build Coastguard Worker            4. If B <: Rational, then __radd_ converts both to the
347*cda5da8dSAndroid Build Coastguard Worker               builtin rational type (hey look, that's us) and
348*cda5da8dSAndroid Build Coastguard Worker               proceeds.
349*cda5da8dSAndroid Build Coastguard Worker            5. Otherwise, __radd__ tries to find the nearest common
350*cda5da8dSAndroid Build Coastguard Worker               base ABC, and fall back to its builtin type. Since this
351*cda5da8dSAndroid Build Coastguard Worker               class doesn't subclass a concrete type, there's no
352*cda5da8dSAndroid Build Coastguard Worker               implementation to fall back to, so we need to try as
353*cda5da8dSAndroid Build Coastguard Worker               hard as possible to return an actual value, or the user
354*cda5da8dSAndroid Build Coastguard Worker               will get a TypeError.
355*cda5da8dSAndroid Build Coastguard Worker
356*cda5da8dSAndroid Build Coastguard Worker        """
357*cda5da8dSAndroid Build Coastguard Worker        def forward(a, b):
358*cda5da8dSAndroid Build Coastguard Worker            if isinstance(b, (int, Fraction)):
359*cda5da8dSAndroid Build Coastguard Worker                return monomorphic_operator(a, b)
360*cda5da8dSAndroid Build Coastguard Worker            elif isinstance(b, float):
361*cda5da8dSAndroid Build Coastguard Worker                return fallback_operator(float(a), b)
362*cda5da8dSAndroid Build Coastguard Worker            elif isinstance(b, complex):
363*cda5da8dSAndroid Build Coastguard Worker                return fallback_operator(complex(a), b)
364*cda5da8dSAndroid Build Coastguard Worker            else:
365*cda5da8dSAndroid Build Coastguard Worker                return NotImplemented
366*cda5da8dSAndroid Build Coastguard Worker        forward.__name__ = '__' + fallback_operator.__name__ + '__'
367*cda5da8dSAndroid Build Coastguard Worker        forward.__doc__ = monomorphic_operator.__doc__
368*cda5da8dSAndroid Build Coastguard Worker
369*cda5da8dSAndroid Build Coastguard Worker        def reverse(b, a):
370*cda5da8dSAndroid Build Coastguard Worker            if isinstance(a, numbers.Rational):
371*cda5da8dSAndroid Build Coastguard Worker                # Includes ints.
372*cda5da8dSAndroid Build Coastguard Worker                return monomorphic_operator(a, b)
373*cda5da8dSAndroid Build Coastguard Worker            elif isinstance(a, numbers.Real):
374*cda5da8dSAndroid Build Coastguard Worker                return fallback_operator(float(a), float(b))
375*cda5da8dSAndroid Build Coastguard Worker            elif isinstance(a, numbers.Complex):
376*cda5da8dSAndroid Build Coastguard Worker                return fallback_operator(complex(a), complex(b))
377*cda5da8dSAndroid Build Coastguard Worker            else:
378*cda5da8dSAndroid Build Coastguard Worker                return NotImplemented
379*cda5da8dSAndroid Build Coastguard Worker        reverse.__name__ = '__r' + fallback_operator.__name__ + '__'
380*cda5da8dSAndroid Build Coastguard Worker        reverse.__doc__ = monomorphic_operator.__doc__
381*cda5da8dSAndroid Build Coastguard Worker
382*cda5da8dSAndroid Build Coastguard Worker        return forward, reverse
383*cda5da8dSAndroid Build Coastguard Worker
384*cda5da8dSAndroid Build Coastguard Worker    # Rational arithmetic algorithms: Knuth, TAOCP, Volume 2, 4.5.1.
385*cda5da8dSAndroid Build Coastguard Worker    #
386*cda5da8dSAndroid Build Coastguard Worker    # Assume input fractions a and b are normalized.
387*cda5da8dSAndroid Build Coastguard Worker    #
388*cda5da8dSAndroid Build Coastguard Worker    # 1) Consider addition/subtraction.
389*cda5da8dSAndroid Build Coastguard Worker    #
390*cda5da8dSAndroid Build Coastguard Worker    # Let g = gcd(da, db). Then
391*cda5da8dSAndroid Build Coastguard Worker    #
392*cda5da8dSAndroid Build Coastguard Worker    #              na   nb    na*db ± nb*da
393*cda5da8dSAndroid Build Coastguard Worker    #     a ± b == -- ± -- == ------------- ==
394*cda5da8dSAndroid Build Coastguard Worker    #              da   db        da*db
395*cda5da8dSAndroid Build Coastguard Worker    #
396*cda5da8dSAndroid Build Coastguard Worker    #              na*(db//g) ± nb*(da//g)    t
397*cda5da8dSAndroid Build Coastguard Worker    #           == ----------------------- == -
398*cda5da8dSAndroid Build Coastguard Worker    #                      (da*db)//g         d
399*cda5da8dSAndroid Build Coastguard Worker    #
400*cda5da8dSAndroid Build Coastguard Worker    # Now, if g > 1, we're working with smaller integers.
401*cda5da8dSAndroid Build Coastguard Worker    #
402*cda5da8dSAndroid Build Coastguard Worker    # Note, that t, (da//g) and (db//g) are pairwise coprime.
403*cda5da8dSAndroid Build Coastguard Worker    #
404*cda5da8dSAndroid Build Coastguard Worker    # Indeed, (da//g) and (db//g) share no common factors (they were
405*cda5da8dSAndroid Build Coastguard Worker    # removed) and da is coprime with na (since input fractions are
406*cda5da8dSAndroid Build Coastguard Worker    # normalized), hence (da//g) and na are coprime.  By symmetry,
407*cda5da8dSAndroid Build Coastguard Worker    # (db//g) and nb are coprime too.  Then,
408*cda5da8dSAndroid Build Coastguard Worker    #
409*cda5da8dSAndroid Build Coastguard Worker    #     gcd(t, da//g) == gcd(na*(db//g), da//g) == 1
410*cda5da8dSAndroid Build Coastguard Worker    #     gcd(t, db//g) == gcd(nb*(da//g), db//g) == 1
411*cda5da8dSAndroid Build Coastguard Worker    #
412*cda5da8dSAndroid Build Coastguard Worker    # Above allows us optimize reduction of the result to lowest
413*cda5da8dSAndroid Build Coastguard Worker    # terms.  Indeed,
414*cda5da8dSAndroid Build Coastguard Worker    #
415*cda5da8dSAndroid Build Coastguard Worker    #     g2 = gcd(t, d) == gcd(t, (da//g)*(db//g)*g) == gcd(t, g)
416*cda5da8dSAndroid Build Coastguard Worker    #
417*cda5da8dSAndroid Build Coastguard Worker    #                       t//g2                   t//g2
418*cda5da8dSAndroid Build Coastguard Worker    #     a ± b == ----------------------- == ----------------
419*cda5da8dSAndroid Build Coastguard Worker    #              (da//g)*(db//g)*(g//g2)    (da//g)*(db//g2)
420*cda5da8dSAndroid Build Coastguard Worker    #
421*cda5da8dSAndroid Build Coastguard Worker    # is a normalized fraction.  This is useful because the unnormalized
422*cda5da8dSAndroid Build Coastguard Worker    # denominator d could be much larger than g.
423*cda5da8dSAndroid Build Coastguard Worker    #
424*cda5da8dSAndroid Build Coastguard Worker    # We should special-case g == 1 (and g2 == 1), since 60.8% of
425*cda5da8dSAndroid Build Coastguard Worker    # randomly-chosen integers are coprime:
426*cda5da8dSAndroid Build Coastguard Worker    # https://en.wikipedia.org/wiki/Coprime_integers#Probability_of_coprimality
427*cda5da8dSAndroid Build Coastguard Worker    # Note, that g2 == 1 always for fractions, obtained from floats: here
428*cda5da8dSAndroid Build Coastguard Worker    # g is a power of 2 and the unnormalized numerator t is an odd integer.
429*cda5da8dSAndroid Build Coastguard Worker    #
430*cda5da8dSAndroid Build Coastguard Worker    # 2) Consider multiplication
431*cda5da8dSAndroid Build Coastguard Worker    #
432*cda5da8dSAndroid Build Coastguard Worker    # Let g1 = gcd(na, db) and g2 = gcd(nb, da), then
433*cda5da8dSAndroid Build Coastguard Worker    #
434*cda5da8dSAndroid Build Coastguard Worker    #            na*nb    na*nb    (na//g1)*(nb//g2)
435*cda5da8dSAndroid Build Coastguard Worker    #     a*b == ----- == ----- == -----------------
436*cda5da8dSAndroid Build Coastguard Worker    #            da*db    db*da    (db//g1)*(da//g2)
437*cda5da8dSAndroid Build Coastguard Worker    #
438*cda5da8dSAndroid Build Coastguard Worker    # Note, that after divisions we're multiplying smaller integers.
439*cda5da8dSAndroid Build Coastguard Worker    #
440*cda5da8dSAndroid Build Coastguard Worker    # Also, the resulting fraction is normalized, because each of
441*cda5da8dSAndroid Build Coastguard Worker    # two factors in the numerator is coprime to each of the two factors
442*cda5da8dSAndroid Build Coastguard Worker    # in the denominator.
443*cda5da8dSAndroid Build Coastguard Worker    #
444*cda5da8dSAndroid Build Coastguard Worker    # Indeed, pick (na//g1).  It's coprime with (da//g2), because input
445*cda5da8dSAndroid Build Coastguard Worker    # fractions are normalized.  It's also coprime with (db//g1), because
446*cda5da8dSAndroid Build Coastguard Worker    # common factors are removed by g1 == gcd(na, db).
447*cda5da8dSAndroid Build Coastguard Worker    #
448*cda5da8dSAndroid Build Coastguard Worker    # As for addition/subtraction, we should special-case g1 == 1
449*cda5da8dSAndroid Build Coastguard Worker    # and g2 == 1 for same reason.  That happens also for multiplying
450*cda5da8dSAndroid Build Coastguard Worker    # rationals, obtained from floats.
451*cda5da8dSAndroid Build Coastguard Worker
452*cda5da8dSAndroid Build Coastguard Worker    def _add(a, b):
453*cda5da8dSAndroid Build Coastguard Worker        """a + b"""
454*cda5da8dSAndroid Build Coastguard Worker        na, da = a.numerator, a.denominator
455*cda5da8dSAndroid Build Coastguard Worker        nb, db = b.numerator, b.denominator
456*cda5da8dSAndroid Build Coastguard Worker        g = math.gcd(da, db)
457*cda5da8dSAndroid Build Coastguard Worker        if g == 1:
458*cda5da8dSAndroid Build Coastguard Worker            return Fraction(na * db + da * nb, da * db, _normalize=False)
459*cda5da8dSAndroid Build Coastguard Worker        s = da // g
460*cda5da8dSAndroid Build Coastguard Worker        t = na * (db // g) + nb * s
461*cda5da8dSAndroid Build Coastguard Worker        g2 = math.gcd(t, g)
462*cda5da8dSAndroid Build Coastguard Worker        if g2 == 1:
463*cda5da8dSAndroid Build Coastguard Worker            return Fraction(t, s * db, _normalize=False)
464*cda5da8dSAndroid Build Coastguard Worker        return Fraction(t // g2, s * (db // g2), _normalize=False)
465*cda5da8dSAndroid Build Coastguard Worker
466*cda5da8dSAndroid Build Coastguard Worker    __add__, __radd__ = _operator_fallbacks(_add, operator.add)
467*cda5da8dSAndroid Build Coastguard Worker
468*cda5da8dSAndroid Build Coastguard Worker    def _sub(a, b):
469*cda5da8dSAndroid Build Coastguard Worker        """a - b"""
470*cda5da8dSAndroid Build Coastguard Worker        na, da = a.numerator, a.denominator
471*cda5da8dSAndroid Build Coastguard Worker        nb, db = b.numerator, b.denominator
472*cda5da8dSAndroid Build Coastguard Worker        g = math.gcd(da, db)
473*cda5da8dSAndroid Build Coastguard Worker        if g == 1:
474*cda5da8dSAndroid Build Coastguard Worker            return Fraction(na * db - da * nb, da * db, _normalize=False)
475*cda5da8dSAndroid Build Coastguard Worker        s = da // g
476*cda5da8dSAndroid Build Coastguard Worker        t = na * (db // g) - nb * s
477*cda5da8dSAndroid Build Coastguard Worker        g2 = math.gcd(t, g)
478*cda5da8dSAndroid Build Coastguard Worker        if g2 == 1:
479*cda5da8dSAndroid Build Coastguard Worker            return Fraction(t, s * db, _normalize=False)
480*cda5da8dSAndroid Build Coastguard Worker        return Fraction(t // g2, s * (db // g2), _normalize=False)
481*cda5da8dSAndroid Build Coastguard Worker
482*cda5da8dSAndroid Build Coastguard Worker    __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub)
483*cda5da8dSAndroid Build Coastguard Worker
484*cda5da8dSAndroid Build Coastguard Worker    def _mul(a, b):
485*cda5da8dSAndroid Build Coastguard Worker        """a * b"""
486*cda5da8dSAndroid Build Coastguard Worker        na, da = a.numerator, a.denominator
487*cda5da8dSAndroid Build Coastguard Worker        nb, db = b.numerator, b.denominator
488*cda5da8dSAndroid Build Coastguard Worker        g1 = math.gcd(na, db)
489*cda5da8dSAndroid Build Coastguard Worker        if g1 > 1:
490*cda5da8dSAndroid Build Coastguard Worker            na //= g1
491*cda5da8dSAndroid Build Coastguard Worker            db //= g1
492*cda5da8dSAndroid Build Coastguard Worker        g2 = math.gcd(nb, da)
493*cda5da8dSAndroid Build Coastguard Worker        if g2 > 1:
494*cda5da8dSAndroid Build Coastguard Worker            nb //= g2
495*cda5da8dSAndroid Build Coastguard Worker            da //= g2
496*cda5da8dSAndroid Build Coastguard Worker        return Fraction(na * nb, db * da, _normalize=False)
497*cda5da8dSAndroid Build Coastguard Worker
498*cda5da8dSAndroid Build Coastguard Worker    __mul__, __rmul__ = _operator_fallbacks(_mul, operator.mul)
499*cda5da8dSAndroid Build Coastguard Worker
500*cda5da8dSAndroid Build Coastguard Worker    def _div(a, b):
501*cda5da8dSAndroid Build Coastguard Worker        """a / b"""
502*cda5da8dSAndroid Build Coastguard Worker        # Same as _mul(), with inversed b.
503*cda5da8dSAndroid Build Coastguard Worker        na, da = a.numerator, a.denominator
504*cda5da8dSAndroid Build Coastguard Worker        nb, db = b.numerator, b.denominator
505*cda5da8dSAndroid Build Coastguard Worker        g1 = math.gcd(na, nb)
506*cda5da8dSAndroid Build Coastguard Worker        if g1 > 1:
507*cda5da8dSAndroid Build Coastguard Worker            na //= g1
508*cda5da8dSAndroid Build Coastguard Worker            nb //= g1
509*cda5da8dSAndroid Build Coastguard Worker        g2 = math.gcd(db, da)
510*cda5da8dSAndroid Build Coastguard Worker        if g2 > 1:
511*cda5da8dSAndroid Build Coastguard Worker            da //= g2
512*cda5da8dSAndroid Build Coastguard Worker            db //= g2
513*cda5da8dSAndroid Build Coastguard Worker        n, d = na * db, nb * da
514*cda5da8dSAndroid Build Coastguard Worker        if d < 0:
515*cda5da8dSAndroid Build Coastguard Worker            n, d = -n, -d
516*cda5da8dSAndroid Build Coastguard Worker        return Fraction(n, d, _normalize=False)
517*cda5da8dSAndroid Build Coastguard Worker
518*cda5da8dSAndroid Build Coastguard Worker    __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv)
519*cda5da8dSAndroid Build Coastguard Worker
520*cda5da8dSAndroid Build Coastguard Worker    def _floordiv(a, b):
521*cda5da8dSAndroid Build Coastguard Worker        """a // b"""
522*cda5da8dSAndroid Build Coastguard Worker        return (a.numerator * b.denominator) // (a.denominator * b.numerator)
523*cda5da8dSAndroid Build Coastguard Worker
524*cda5da8dSAndroid Build Coastguard Worker    __floordiv__, __rfloordiv__ = _operator_fallbacks(_floordiv, operator.floordiv)
525*cda5da8dSAndroid Build Coastguard Worker
526*cda5da8dSAndroid Build Coastguard Worker    def _divmod(a, b):
527*cda5da8dSAndroid Build Coastguard Worker        """(a // b, a % b)"""
528*cda5da8dSAndroid Build Coastguard Worker        da, db = a.denominator, b.denominator
529*cda5da8dSAndroid Build Coastguard Worker        div, n_mod = divmod(a.numerator * db, da * b.numerator)
530*cda5da8dSAndroid Build Coastguard Worker        return div, Fraction(n_mod, da * db)
531*cda5da8dSAndroid Build Coastguard Worker
532*cda5da8dSAndroid Build Coastguard Worker    __divmod__, __rdivmod__ = _operator_fallbacks(_divmod, divmod)
533*cda5da8dSAndroid Build Coastguard Worker
534*cda5da8dSAndroid Build Coastguard Worker    def _mod(a, b):
535*cda5da8dSAndroid Build Coastguard Worker        """a % b"""
536*cda5da8dSAndroid Build Coastguard Worker        da, db = a.denominator, b.denominator
537*cda5da8dSAndroid Build Coastguard Worker        return Fraction((a.numerator * db) % (b.numerator * da), da * db)
538*cda5da8dSAndroid Build Coastguard Worker
539*cda5da8dSAndroid Build Coastguard Worker    __mod__, __rmod__ = _operator_fallbacks(_mod, operator.mod)
540*cda5da8dSAndroid Build Coastguard Worker
541*cda5da8dSAndroid Build Coastguard Worker    def __pow__(a, b):
542*cda5da8dSAndroid Build Coastguard Worker        """a ** b
543*cda5da8dSAndroid Build Coastguard Worker
544*cda5da8dSAndroid Build Coastguard Worker        If b is not an integer, the result will be a float or complex
545*cda5da8dSAndroid Build Coastguard Worker        since roots are generally irrational. If b is an integer, the
546*cda5da8dSAndroid Build Coastguard Worker        result will be rational.
547*cda5da8dSAndroid Build Coastguard Worker
548*cda5da8dSAndroid Build Coastguard Worker        """
549*cda5da8dSAndroid Build Coastguard Worker        if isinstance(b, numbers.Rational):
550*cda5da8dSAndroid Build Coastguard Worker            if b.denominator == 1:
551*cda5da8dSAndroid Build Coastguard Worker                power = b.numerator
552*cda5da8dSAndroid Build Coastguard Worker                if power >= 0:
553*cda5da8dSAndroid Build Coastguard Worker                    return Fraction(a._numerator ** power,
554*cda5da8dSAndroid Build Coastguard Worker                                    a._denominator ** power,
555*cda5da8dSAndroid Build Coastguard Worker                                    _normalize=False)
556*cda5da8dSAndroid Build Coastguard Worker                elif a._numerator >= 0:
557*cda5da8dSAndroid Build Coastguard Worker                    return Fraction(a._denominator ** -power,
558*cda5da8dSAndroid Build Coastguard Worker                                    a._numerator ** -power,
559*cda5da8dSAndroid Build Coastguard Worker                                    _normalize=False)
560*cda5da8dSAndroid Build Coastguard Worker                else:
561*cda5da8dSAndroid Build Coastguard Worker                    return Fraction((-a._denominator) ** -power,
562*cda5da8dSAndroid Build Coastguard Worker                                    (-a._numerator) ** -power,
563*cda5da8dSAndroid Build Coastguard Worker                                    _normalize=False)
564*cda5da8dSAndroid Build Coastguard Worker            else:
565*cda5da8dSAndroid Build Coastguard Worker                # A fractional power will generally produce an
566*cda5da8dSAndroid Build Coastguard Worker                # irrational number.
567*cda5da8dSAndroid Build Coastguard Worker                return float(a) ** float(b)
568*cda5da8dSAndroid Build Coastguard Worker        else:
569*cda5da8dSAndroid Build Coastguard Worker            return float(a) ** b
570*cda5da8dSAndroid Build Coastguard Worker
571*cda5da8dSAndroid Build Coastguard Worker    def __rpow__(b, a):
572*cda5da8dSAndroid Build Coastguard Worker        """a ** b"""
573*cda5da8dSAndroid Build Coastguard Worker        if b._denominator == 1 and b._numerator >= 0:
574*cda5da8dSAndroid Build Coastguard Worker            # If a is an int, keep it that way if possible.
575*cda5da8dSAndroid Build Coastguard Worker            return a ** b._numerator
576*cda5da8dSAndroid Build Coastguard Worker
577*cda5da8dSAndroid Build Coastguard Worker        if isinstance(a, numbers.Rational):
578*cda5da8dSAndroid Build Coastguard Worker            return Fraction(a.numerator, a.denominator) ** b
579*cda5da8dSAndroid Build Coastguard Worker
580*cda5da8dSAndroid Build Coastguard Worker        if b._denominator == 1:
581*cda5da8dSAndroid Build Coastguard Worker            return a ** b._numerator
582*cda5da8dSAndroid Build Coastguard Worker
583*cda5da8dSAndroid Build Coastguard Worker        return a ** float(b)
584*cda5da8dSAndroid Build Coastguard Worker
585*cda5da8dSAndroid Build Coastguard Worker    def __pos__(a):
586*cda5da8dSAndroid Build Coastguard Worker        """+a: Coerces a subclass instance to Fraction"""
587*cda5da8dSAndroid Build Coastguard Worker        return Fraction(a._numerator, a._denominator, _normalize=False)
588*cda5da8dSAndroid Build Coastguard Worker
589*cda5da8dSAndroid Build Coastguard Worker    def __neg__(a):
590*cda5da8dSAndroid Build Coastguard Worker        """-a"""
591*cda5da8dSAndroid Build Coastguard Worker        return Fraction(-a._numerator, a._denominator, _normalize=False)
592*cda5da8dSAndroid Build Coastguard Worker
593*cda5da8dSAndroid Build Coastguard Worker    def __abs__(a):
594*cda5da8dSAndroid Build Coastguard Worker        """abs(a)"""
595*cda5da8dSAndroid Build Coastguard Worker        return Fraction(abs(a._numerator), a._denominator, _normalize=False)
596*cda5da8dSAndroid Build Coastguard Worker
597*cda5da8dSAndroid Build Coastguard Worker    def __int__(a, _index=operator.index):
598*cda5da8dSAndroid Build Coastguard Worker        """int(a)"""
599*cda5da8dSAndroid Build Coastguard Worker        if a._numerator < 0:
600*cda5da8dSAndroid Build Coastguard Worker            return _index(-(-a._numerator // a._denominator))
601*cda5da8dSAndroid Build Coastguard Worker        else:
602*cda5da8dSAndroid Build Coastguard Worker            return _index(a._numerator // a._denominator)
603*cda5da8dSAndroid Build Coastguard Worker
604*cda5da8dSAndroid Build Coastguard Worker    def __trunc__(a):
605*cda5da8dSAndroid Build Coastguard Worker        """math.trunc(a)"""
606*cda5da8dSAndroid Build Coastguard Worker        if a._numerator < 0:
607*cda5da8dSAndroid Build Coastguard Worker            return -(-a._numerator // a._denominator)
608*cda5da8dSAndroid Build Coastguard Worker        else:
609*cda5da8dSAndroid Build Coastguard Worker            return a._numerator // a._denominator
610*cda5da8dSAndroid Build Coastguard Worker
611*cda5da8dSAndroid Build Coastguard Worker    def __floor__(a):
612*cda5da8dSAndroid Build Coastguard Worker        """math.floor(a)"""
613*cda5da8dSAndroid Build Coastguard Worker        return a.numerator // a.denominator
614*cda5da8dSAndroid Build Coastguard Worker
615*cda5da8dSAndroid Build Coastguard Worker    def __ceil__(a):
616*cda5da8dSAndroid Build Coastguard Worker        """math.ceil(a)"""
617*cda5da8dSAndroid Build Coastguard Worker        # The negations cleverly convince floordiv to return the ceiling.
618*cda5da8dSAndroid Build Coastguard Worker        return -(-a.numerator // a.denominator)
619*cda5da8dSAndroid Build Coastguard Worker
620*cda5da8dSAndroid Build Coastguard Worker    def __round__(self, ndigits=None):
621*cda5da8dSAndroid Build Coastguard Worker        """round(self, ndigits)
622*cda5da8dSAndroid Build Coastguard Worker
623*cda5da8dSAndroid Build Coastguard Worker        Rounds half toward even.
624*cda5da8dSAndroid Build Coastguard Worker        """
625*cda5da8dSAndroid Build Coastguard Worker        if ndigits is None:
626*cda5da8dSAndroid Build Coastguard Worker            floor, remainder = divmod(self.numerator, self.denominator)
627*cda5da8dSAndroid Build Coastguard Worker            if remainder * 2 < self.denominator:
628*cda5da8dSAndroid Build Coastguard Worker                return floor
629*cda5da8dSAndroid Build Coastguard Worker            elif remainder * 2 > self.denominator:
630*cda5da8dSAndroid Build Coastguard Worker                return floor + 1
631*cda5da8dSAndroid Build Coastguard Worker            # Deal with the half case:
632*cda5da8dSAndroid Build Coastguard Worker            elif floor % 2 == 0:
633*cda5da8dSAndroid Build Coastguard Worker                return floor
634*cda5da8dSAndroid Build Coastguard Worker            else:
635*cda5da8dSAndroid Build Coastguard Worker                return floor + 1
636*cda5da8dSAndroid Build Coastguard Worker        shift = 10**abs(ndigits)
637*cda5da8dSAndroid Build Coastguard Worker        # See _operator_fallbacks.forward to check that the results of
638*cda5da8dSAndroid Build Coastguard Worker        # these operations will always be Fraction and therefore have
639*cda5da8dSAndroid Build Coastguard Worker        # round().
640*cda5da8dSAndroid Build Coastguard Worker        if ndigits > 0:
641*cda5da8dSAndroid Build Coastguard Worker            return Fraction(round(self * shift), shift)
642*cda5da8dSAndroid Build Coastguard Worker        else:
643*cda5da8dSAndroid Build Coastguard Worker            return Fraction(round(self / shift) * shift)
644*cda5da8dSAndroid Build Coastguard Worker
645*cda5da8dSAndroid Build Coastguard Worker    def __hash__(self):
646*cda5da8dSAndroid Build Coastguard Worker        """hash(self)"""
647*cda5da8dSAndroid Build Coastguard Worker
648*cda5da8dSAndroid Build Coastguard Worker        # To make sure that the hash of a Fraction agrees with the hash
649*cda5da8dSAndroid Build Coastguard Worker        # of a numerically equal integer, float or Decimal instance, we
650*cda5da8dSAndroid Build Coastguard Worker        # follow the rules for numeric hashes outlined in the
651*cda5da8dSAndroid Build Coastguard Worker        # documentation.  (See library docs, 'Built-in Types').
652*cda5da8dSAndroid Build Coastguard Worker
653*cda5da8dSAndroid Build Coastguard Worker        try:
654*cda5da8dSAndroid Build Coastguard Worker            dinv = pow(self._denominator, -1, _PyHASH_MODULUS)
655*cda5da8dSAndroid Build Coastguard Worker        except ValueError:
656*cda5da8dSAndroid Build Coastguard Worker            # ValueError means there is no modular inverse.
657*cda5da8dSAndroid Build Coastguard Worker            hash_ = _PyHASH_INF
658*cda5da8dSAndroid Build Coastguard Worker        else:
659*cda5da8dSAndroid Build Coastguard Worker            # The general algorithm now specifies that the absolute value of
660*cda5da8dSAndroid Build Coastguard Worker            # the hash is
661*cda5da8dSAndroid Build Coastguard Worker            #    (|N| * dinv) % P
662*cda5da8dSAndroid Build Coastguard Worker            # where N is self._numerator and P is _PyHASH_MODULUS.  That's
663*cda5da8dSAndroid Build Coastguard Worker            # optimized here in two ways:  first, for a non-negative int i,
664*cda5da8dSAndroid Build Coastguard Worker            # hash(i) == i % P, but the int hash implementation doesn't need
665*cda5da8dSAndroid Build Coastguard Worker            # to divide, and is faster than doing % P explicitly.  So we do
666*cda5da8dSAndroid Build Coastguard Worker            #    hash(|N| * dinv)
667*cda5da8dSAndroid Build Coastguard Worker            # instead.  Second, N is unbounded, so its product with dinv may
668*cda5da8dSAndroid Build Coastguard Worker            # be arbitrarily expensive to compute.  The final answer is the
669*cda5da8dSAndroid Build Coastguard Worker            # same if we use the bounded |N| % P instead, which can again
670*cda5da8dSAndroid Build Coastguard Worker            # be done with an int hash() call.  If 0 <= i < P, hash(i) == i,
671*cda5da8dSAndroid Build Coastguard Worker            # so this nested hash() call wastes a bit of time making a
672*cda5da8dSAndroid Build Coastguard Worker            # redundant copy when |N| < P, but can save an arbitrarily large
673*cda5da8dSAndroid Build Coastguard Worker            # amount of computation for large |N|.
674*cda5da8dSAndroid Build Coastguard Worker            hash_ = hash(hash(abs(self._numerator)) * dinv)
675*cda5da8dSAndroid Build Coastguard Worker        result = hash_ if self._numerator >= 0 else -hash_
676*cda5da8dSAndroid Build Coastguard Worker        return -2 if result == -1 else result
677*cda5da8dSAndroid Build Coastguard Worker
678*cda5da8dSAndroid Build Coastguard Worker    def __eq__(a, b):
679*cda5da8dSAndroid Build Coastguard Worker        """a == b"""
680*cda5da8dSAndroid Build Coastguard Worker        if type(b) is int:
681*cda5da8dSAndroid Build Coastguard Worker            return a._numerator == b and a._denominator == 1
682*cda5da8dSAndroid Build Coastguard Worker        if isinstance(b, numbers.Rational):
683*cda5da8dSAndroid Build Coastguard Worker            return (a._numerator == b.numerator and
684*cda5da8dSAndroid Build Coastguard Worker                    a._denominator == b.denominator)
685*cda5da8dSAndroid Build Coastguard Worker        if isinstance(b, numbers.Complex) and b.imag == 0:
686*cda5da8dSAndroid Build Coastguard Worker            b = b.real
687*cda5da8dSAndroid Build Coastguard Worker        if isinstance(b, float):
688*cda5da8dSAndroid Build Coastguard Worker            if math.isnan(b) or math.isinf(b):
689*cda5da8dSAndroid Build Coastguard Worker                # comparisons with an infinity or nan should behave in
690*cda5da8dSAndroid Build Coastguard Worker                # the same way for any finite a, so treat a as zero.
691*cda5da8dSAndroid Build Coastguard Worker                return 0.0 == b
692*cda5da8dSAndroid Build Coastguard Worker            else:
693*cda5da8dSAndroid Build Coastguard Worker                return a == a.from_float(b)
694*cda5da8dSAndroid Build Coastguard Worker        else:
695*cda5da8dSAndroid Build Coastguard Worker            # Since a doesn't know how to compare with b, let's give b
696*cda5da8dSAndroid Build Coastguard Worker            # a chance to compare itself with a.
697*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
698*cda5da8dSAndroid Build Coastguard Worker
699*cda5da8dSAndroid Build Coastguard Worker    def _richcmp(self, other, op):
700*cda5da8dSAndroid Build Coastguard Worker        """Helper for comparison operators, for internal use only.
701*cda5da8dSAndroid Build Coastguard Worker
702*cda5da8dSAndroid Build Coastguard Worker        Implement comparison between a Rational instance `self`, and
703*cda5da8dSAndroid Build Coastguard Worker        either another Rational instance or a float `other`.  If
704*cda5da8dSAndroid Build Coastguard Worker        `other` is not a Rational instance or a float, return
705*cda5da8dSAndroid Build Coastguard Worker        NotImplemented. `op` should be one of the six standard
706*cda5da8dSAndroid Build Coastguard Worker        comparison operators.
707*cda5da8dSAndroid Build Coastguard Worker
708*cda5da8dSAndroid Build Coastguard Worker        """
709*cda5da8dSAndroid Build Coastguard Worker        # convert other to a Rational instance where reasonable.
710*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, numbers.Rational):
711*cda5da8dSAndroid Build Coastguard Worker            return op(self._numerator * other.denominator,
712*cda5da8dSAndroid Build Coastguard Worker                      self._denominator * other.numerator)
713*cda5da8dSAndroid Build Coastguard Worker        if isinstance(other, float):
714*cda5da8dSAndroid Build Coastguard Worker            if math.isnan(other) or math.isinf(other):
715*cda5da8dSAndroid Build Coastguard Worker                return op(0.0, other)
716*cda5da8dSAndroid Build Coastguard Worker            else:
717*cda5da8dSAndroid Build Coastguard Worker                return op(self, self.from_float(other))
718*cda5da8dSAndroid Build Coastguard Worker        else:
719*cda5da8dSAndroid Build Coastguard Worker            return NotImplemented
720*cda5da8dSAndroid Build Coastguard Worker
721*cda5da8dSAndroid Build Coastguard Worker    def __lt__(a, b):
722*cda5da8dSAndroid Build Coastguard Worker        """a < b"""
723*cda5da8dSAndroid Build Coastguard Worker        return a._richcmp(b, operator.lt)
724*cda5da8dSAndroid Build Coastguard Worker
725*cda5da8dSAndroid Build Coastguard Worker    def __gt__(a, b):
726*cda5da8dSAndroid Build Coastguard Worker        """a > b"""
727*cda5da8dSAndroid Build Coastguard Worker        return a._richcmp(b, operator.gt)
728*cda5da8dSAndroid Build Coastguard Worker
729*cda5da8dSAndroid Build Coastguard Worker    def __le__(a, b):
730*cda5da8dSAndroid Build Coastguard Worker        """a <= b"""
731*cda5da8dSAndroid Build Coastguard Worker        return a._richcmp(b, operator.le)
732*cda5da8dSAndroid Build Coastguard Worker
733*cda5da8dSAndroid Build Coastguard Worker    def __ge__(a, b):
734*cda5da8dSAndroid Build Coastguard Worker        """a >= b"""
735*cda5da8dSAndroid Build Coastguard Worker        return a._richcmp(b, operator.ge)
736*cda5da8dSAndroid Build Coastguard Worker
737*cda5da8dSAndroid Build Coastguard Worker    def __bool__(a):
738*cda5da8dSAndroid Build Coastguard Worker        """a != 0"""
739*cda5da8dSAndroid Build Coastguard Worker        # bpo-39274: Use bool() because (a._numerator != 0) can return an
740*cda5da8dSAndroid Build Coastguard Worker        # object which is not a bool.
741*cda5da8dSAndroid Build Coastguard Worker        return bool(a._numerator)
742*cda5da8dSAndroid Build Coastguard Worker
743*cda5da8dSAndroid Build Coastguard Worker    # support for pickling, copy, and deepcopy
744*cda5da8dSAndroid Build Coastguard Worker
745*cda5da8dSAndroid Build Coastguard Worker    def __reduce__(self):
746*cda5da8dSAndroid Build Coastguard Worker        return (self.__class__, (self._numerator, self._denominator))
747*cda5da8dSAndroid Build Coastguard Worker
748*cda5da8dSAndroid Build Coastguard Worker    def __copy__(self):
749*cda5da8dSAndroid Build Coastguard Worker        if type(self) == Fraction:
750*cda5da8dSAndroid Build Coastguard Worker            return self     # I'm immutable; therefore I am my own clone
751*cda5da8dSAndroid Build Coastguard Worker        return self.__class__(self._numerator, self._denominator)
752*cda5da8dSAndroid Build Coastguard Worker
753*cda5da8dSAndroid Build Coastguard Worker    def __deepcopy__(self, memo):
754*cda5da8dSAndroid Build Coastguard Worker        if type(self) == Fraction:
755*cda5da8dSAndroid Build Coastguard Worker            return self     # My components are also immutable
756*cda5da8dSAndroid Build Coastguard Worker        return self.__class__(self._numerator, self._denominator)
757