fractions.py revision dc2964b0d849389bffde95b8f76fd112049e114f
1d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin# Originally contributed by Sjoerd Mullender.
2d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin# Significantly modified by Jeffrey Yasskin <jyasskin at gmail.com>.
3d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
4d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin"""Rational, infinite-precision, real numbers."""
5d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
6d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskinfrom __future__ import division
7d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskinimport math
8d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskinimport numbers
9d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskinimport operator
1045169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskinimport re
11d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
12d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin__all__ = ["Rational"]
13d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
14d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey YasskinRationalAbc = numbers.Rational
15d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
16d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
173e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskindef gcd(a, b):
183e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin    """Calculate the Greatest Common Divisor of a and b.
19d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
20d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    Unless b==0, the result will have the same sign as b (so that when
21d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    b is divided by it, the result comes out positive).
22d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    """
23d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    while b:
24d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        a, b = b, a%b
25d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    return a
26d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
27d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
2845169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin_RATIONAL_FORMAT = re.compile(
293e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin    r'^\s*(?P<sign>[-+]?)(?P<num>\d+)'
303e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin    r'(?:/(?P<denom>\d+)|\.(?P<decimal>\d+))?\s*$')
3145169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin
3245169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin
33d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskinclass Rational(RationalAbc):
34d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    """This class implements rational numbers.
35d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
36d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    Rational(8, 6) will produce a rational number equivalent to
37d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    4/3. Both arguments must be Integral. The numerator defaults to 0
38d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    and the denominator defaults to 1 so that Rational(3) == 3 and
39d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    Rational() == 0.
40d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
4145169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin    Rationals can also be constructed from strings of the form
423e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin    '[-+]?[0-9]+((/|.)[0-9]+)?', optionally surrounded by spaces.
4345169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin
44d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    """
45d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
46dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin    __slots__ = ('_numerator', '_denominator')
47d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
4845169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin    # We're immutable, so use __new__ not __init__
4945169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin    def __new__(cls, numerator=0, denominator=1):
5045169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        """Constructs a Rational.
5145169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin
5263c77b61751c2d15754b6381d085eb5ca2e26501Raymond Hettinger        Takes a string like '3/2' or '1.5', another Rational, or a
533e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin        numerator/denominator pair.
5445169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin
5545169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        """
5645169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        self = super(Rational, cls).__new__(cls)
5745169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin
5845169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        if denominator == 1:
5945169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin            if isinstance(numerator, basestring):
6045169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                # Handle construction from strings.
6145169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                input = numerator
6245169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                m = _RATIONAL_FORMAT.match(input)
6345169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                if m is None:
6445169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                    raise ValueError('Invalid literal for Rational: ' + input)
653e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                numerator = m.group('num')
663e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                decimal = m.group('decimal')
673e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                if decimal:
683e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                    # The literal is a decimal number.
693e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                    numerator = int(numerator + decimal)
703e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                    denominator = 10**len(decimal)
713e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                else:
723e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                    # The literal is an integer or fraction.
733e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                    numerator = int(numerator)
743e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                    # Default denominator to 1.
753e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin                    denominator = int(m.group('denom') or 1)
763e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin
7745169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                if m.group('sign') == '-':
7845169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                    numerator = -numerator
7945169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin
8045169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin            elif (not isinstance(numerator, numbers.Integral) and
8145169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                  isinstance(numerator, RationalAbc)):
8245169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                # Handle copies from other rationals.
8345169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                other_rational = numerator
8445169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                numerator = other_rational.numerator
8545169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                denominator = other_rational.denominator
86d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
87d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if (not isinstance(numerator, numbers.Integral) or
88d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            not isinstance(denominator, numbers.Integral)):
89d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            raise TypeError("Rational(%(numerator)s, %(denominator)s):"
90d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                            " Both arguments must be integral." % locals())
91d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
92d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if denominator == 0:
93d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            raise ZeroDivisionError('Rational(%s, 0)' % numerator)
94d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
953e1a3736169fbd7e1a2234899faa64e5de75bc3eJeffrey Yasskin        g = gcd(numerator, denominator)
96dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin        self._numerator = int(numerator // g)
97dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin        self._denominator = int(denominator // g)
9845169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        return self
99d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
100d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    @classmethod
101d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def from_float(cls, f):
10245169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        """Converts a finite float to a rational number, exactly.
10345169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin
10445169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        Beware that Rational.from_float(0.3) != Rational(3, 10).
10545169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin
10645169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        """
107d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if not isinstance(f, float):
108d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            raise TypeError("%s.from_float() only takes floats, not %r (%s)" %
109d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                            (cls.__name__, f, type(f).__name__))
110d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if math.isnan(f) or math.isinf(f):
111d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            raise TypeError("Cannot convert %r to %s." % (f, cls.__name__))
1123ea7b41b5805c60a05e697211d0bfc14a62a19fbJeffrey Yasskin        return cls(*f.as_integer_ratio())
113d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
11445169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin    @classmethod
11545169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin    def from_decimal(cls, dec):
11645169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        """Converts a finite Decimal instance to a rational number, exactly."""
11745169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        from decimal import Decimal
11845169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        if not isinstance(dec, Decimal):
11945169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin            raise TypeError(
12045169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                "%s.from_decimal() only takes Decimals, not %r (%s)" %
12145169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin                (cls.__name__, dec, type(dec).__name__))
12245169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        if not dec.is_finite():
12345169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin            # Catches infinities and nans.
12445169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin            raise TypeError("Cannot convert %s to %s." % (dec, cls.__name__))
12545169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        sign, digits, exp = dec.as_tuple()
12645169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        digits = int(''.join(map(str, digits)))
12745169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        if sign:
12845169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin            digits = -digits
12945169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        if exp >= 0:
13045169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin            return cls(digits * 10 ** exp)
13145169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        else:
13245169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin            return cls(digits, 10 ** -exp)
13345169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin
134cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger    @classmethod
135cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger    def from_continued_fraction(cls, seq):
136cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        'Build a Rational from a continued fraction expessed as a sequence'
137cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        n, d = 1, 0
138cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        for e in reversed(seq):
139cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger            n, d = d, n
140cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger            n += e * d
141f336c8b7e91f389c8af4255f589849b16ee3dcb5Raymond Hettinger        return cls(n, d) if seq else cls(0)
142cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger
143cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger    def as_continued_fraction(self):
144cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        'Return continued fraction expressed as a list'
145cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        n = self.numerator
146cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        d = self.denominator
147cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        cf = []
148cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        while d:
149cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger            e = int(n // d)
150cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger            cf.append(e)
151cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger            n -= e * d
152cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger            n, d = d, n
153cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        return cf
154cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger
1559c6d81f5dd083ad536106bf723f705d70ddbe258Raymond Hettinger    def approximate(self, max_denominator):
1569c6d81f5dd083ad536106bf723f705d70ddbe258Raymond Hettinger        'Best rational approximation with a denominator <= max_denominator'
157cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        # XXX First cut at algorithm
158cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        # Still needs rounding rules as specified at
159cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        #       http://en.wikipedia.org/wiki/Continued_fraction
1609c6d81f5dd083ad536106bf723f705d70ddbe258Raymond Hettinger        if self.denominator <= max_denominator:
1619c6d81f5dd083ad536106bf723f705d70ddbe258Raymond Hettinger            return self
1629c6d81f5dd083ad536106bf723f705d70ddbe258Raymond Hettinger        cf = self.as_continued_fraction()
163eb461904eb277c5a92a7d2672f941cb095cf1a93Raymond Hettinger        result = Rational(0)
164cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        for i in range(1, len(cf)):
1659c6d81f5dd083ad536106bf723f705d70ddbe258Raymond Hettinger            new = self.from_continued_fraction(cf[:i])
166cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger            if new.denominator > max_denominator:
167cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger                break
168cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger            result = new
169cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger        return result
170cf10926088c1e8a4f2d3097e095fa0fd7d5d681aRaymond Hettinger
171dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin    @property
172dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin    def numerator(a):
173dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin        return a._numerator
174dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin
175dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin    @property
176dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin    def denominator(a):
177dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin        return a._denominator
178dc2964b0d849389bffde95b8f76fd112049e114fJeffrey Yasskin
179d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __repr__(self):
180d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """repr(self)"""
18145169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin        return ('Rational(%r,%r)' % (self.numerator, self.denominator))
182d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
183d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __str__(self):
184d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """str(self)"""
185d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if self.denominator == 1:
186d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return str(self.numerator)
187d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        else:
18845169fbc800d573ddd01d3f440f264caaa93c622Jeffrey Yasskin            return '%s/%s' % (self.numerator, self.denominator)
189d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
190d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def _operator_fallbacks(monomorphic_operator, fallback_operator):
191d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """Generates forward and reverse operators given a purely-rational
192d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        operator and a function from the operator module.
193d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
194d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        Use this like:
195d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        __op__, __rop__ = _operator_fallbacks(just_rational_op, operator.op)
196d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
197b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        In general, we want to implement the arithmetic operations so
198b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        that mixed-mode operations either call an implementation whose
199b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        author knew about the types of both arguments, or convert both
200b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        to the nearest built in type and do the operation there. In
201b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        Rational, that means that we define __add__ and __radd__ as:
202b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin
203b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin            def __add__(self, other):
2042df20a3e0816537db68618cef0603e89773beac4Raymond Hettinger                # Both types have numerators/denominator attributes,
2052df20a3e0816537db68618cef0603e89773beac4Raymond Hettinger                # so do the operation directly
206b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                if isinstance(other, (int, long, Rational)):
207b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                    return Rational(self.numerator * other.denominator +
208b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                                    other.numerator * self.denominator,
209b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                                    self.denominator * other.denominator)
2102df20a3e0816537db68618cef0603e89773beac4Raymond Hettinger                # float and complex don't have those operations, but we
2112df20a3e0816537db68618cef0603e89773beac4Raymond Hettinger                # know about those types, so special case them.
212b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                elif isinstance(other, float):
213b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                    return float(self) + other
214b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                elif isinstance(other, complex):
215b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                    return complex(self) + other
2162df20a3e0816537db68618cef0603e89773beac4Raymond Hettinger                # Let the other type take over.
2172df20a3e0816537db68618cef0603e89773beac4Raymond Hettinger                return NotImplemented
218b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin
219b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin            def __radd__(self, other):
220b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                # radd handles more types than add because there's
221b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                # nothing left to fall back to.
222b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                if isinstance(other, RationalAbc):
223b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                    return Rational(self.numerator * other.denominator +
224b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                                    other.numerator * self.denominator,
225b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                                    self.denominator * other.denominator)
226b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                elif isinstance(other, Real):
227b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                    return float(other) + float(self)
228b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                elif isinstance(other, Complex):
229b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin                    return complex(other) + complex(self)
2302df20a3e0816537db68618cef0603e89773beac4Raymond Hettinger                return NotImplemented
231b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin
232b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin
233b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        There are 5 different cases for a mixed-type addition on
234b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        Rational. I'll refer to all of the above code that doesn't
235b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        refer to Rational, float, or complex as "boilerplate". 'r'
236b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        will be an instance of Rational, which is a subtype of
237b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        RationalAbc (r : Rational <: RationalAbc), and b : B <:
238b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        Complex. The first three involve 'r + b':
239b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin
240b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin            1. If B <: Rational, int, float, or complex, we handle
241b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               that specially, and all is well.
242b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin            2. If Rational falls back to the boilerplate code, and it
243b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               were to return a value from __add__, we'd miss the
244b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               possibility that B defines a more intelligent __radd__,
245b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               so the boilerplate should return NotImplemented from
246b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               __add__. In particular, we don't handle RationalAbc
247b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               here, even though we could get an exact answer, in case
248b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               the other type wants to do something special.
249b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin            3. If B <: Rational, Python tries B.__radd__ before
250b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               Rational.__add__. This is ok, because it was
251b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               implemented with knowledge of Rational, so it can
252b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               handle those instances before delegating to Real or
253b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               Complex.
254b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin
255b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        The next two situations describe 'b + r'. We assume that b
256b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        didn't know about Rational in its implementation, and that it
257b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin        uses similar boilerplate code:
258b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin
259b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin            4. If B <: RationalAbc, then __radd_ converts both to the
260b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               builtin rational type (hey look, that's us) and
261b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               proceeds.
262b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin            5. Otherwise, __radd__ tries to find the nearest common
263b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               base ABC, and fall back to its builtin type. Since this
264b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               class doesn't subclass a concrete type, there's no
265b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               implementation to fall back to, so we need to try as
266b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               hard as possible to return an actual value, or the user
267b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin               will get a TypeError.
268b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin
269d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """
270d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        def forward(a, b):
271b23dea6adb7eaf3f415e05b129afa01fa1c4dd5cJeffrey Yasskin            if isinstance(b, (int, long, Rational)):
272d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                return monomorphic_operator(a, b)
273d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            elif isinstance(b, float):
274d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                return fallback_operator(float(a), b)
275d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            elif isinstance(b, complex):
276d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                return fallback_operator(complex(a), b)
277d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            else:
278d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                return NotImplemented
279d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        forward.__name__ = '__' + fallback_operator.__name__ + '__'
280d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        forward.__doc__ = monomorphic_operator.__doc__
281d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
282d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        def reverse(b, a):
283d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            if isinstance(a, RationalAbc):
284d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                # Includes ints.
285d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                return monomorphic_operator(a, b)
286d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            elif isinstance(a, numbers.Real):
287d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                return fallback_operator(float(a), float(b))
288d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            elif isinstance(a, numbers.Complex):
289d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                return fallback_operator(complex(a), complex(b))
290d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            else:
291d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                return NotImplemented
292d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        reverse.__name__ = '__r' + fallback_operator.__name__ + '__'
293d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        reverse.__doc__ = monomorphic_operator.__doc__
294d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
295d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return forward, reverse
296d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
297d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def _add(a, b):
298d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a + b"""
299d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return Rational(a.numerator * b.denominator +
300d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                        b.numerator * a.denominator,
301d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                        a.denominator * b.denominator)
302d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
303d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    __add__, __radd__ = _operator_fallbacks(_add, operator.add)
304d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
305d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def _sub(a, b):
306d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a - b"""
307d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return Rational(a.numerator * b.denominator -
308d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                        b.numerator * a.denominator,
309d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                        a.denominator * b.denominator)
310d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
311d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub)
312d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
313d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def _mul(a, b):
314d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a * b"""
315d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return Rational(a.numerator * b.numerator, a.denominator * b.denominator)
316d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
317d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    __mul__, __rmul__ = _operator_fallbacks(_mul, operator.mul)
318d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
319d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def _div(a, b):
320d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a / b"""
321d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return Rational(a.numerator * b.denominator,
322d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                        a.denominator * b.numerator)
323d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
324d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv)
325d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    __div__, __rdiv__ = _operator_fallbacks(_div, operator.div)
326d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
327909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger    def __floordiv__(a, b):
328909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger        """a // b"""
329909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger        # Will be math.floor(a / b) in 3.0.
330d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        div = a / b
331d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if isinstance(div, RationalAbc):
332d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # trunc(math.floor(div)) doesn't work if the rational is
333d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # more precise than a float because the intermediate
334d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # rounding may cross an integer boundary.
335d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return div.numerator // div.denominator
336d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        else:
337d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return math.floor(div)
338d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
339d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __rfloordiv__(b, a):
340d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a // b"""
341d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        # Will be math.floor(a / b) in 3.0.
342909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger        div = a / b
343909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger        if isinstance(div, RationalAbc):
344909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger            # trunc(math.floor(div)) doesn't work if the rational is
345909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger            # more precise than a float because the intermediate
346909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger            # rounding may cross an integer boundary.
347909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger            return div.numerator // div.denominator
348909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger        else:
349909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger            return math.floor(div)
350d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
351d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __mod__(a, b):
352d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a % b"""
353909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger        div = a // b
354909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger        return a - b * div
355d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
356d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __rmod__(b, a):
357d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a % b"""
358909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger        div = a // b
359909e334e8a525e8430f1532c0ecf133f19d3d185Raymond Hettinger        return a - b * div
360d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
361d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __pow__(a, b):
362d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a ** b
363d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
364d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        If b is not an integer, the result will be a float or complex
365d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        since roots are generally irrational. If b is an integer, the
366d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        result will be rational.
367d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
368d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """
369d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if isinstance(b, RationalAbc):
370d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            if b.denominator == 1:
371d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                power = b.numerator
372d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                if power >= 0:
373d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                    return Rational(a.numerator ** power,
374d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                                    a.denominator ** power)
375d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                else:
376d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                    return Rational(a.denominator ** -power,
377d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                                    a.numerator ** -power)
378d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            else:
379d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                # A fractional power will generally produce an
380d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                # irrational number.
381d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                return float(a) ** float(b)
382d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        else:
383d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return float(a) ** b
384d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
385d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __rpow__(b, a):
386d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a ** b"""
387d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if b.denominator == 1 and b.numerator >= 0:
388d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # If a is an int, keep it that way if possible.
389d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return a ** b.numerator
390d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
391d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if isinstance(a, RationalAbc):
392d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return Rational(a.numerator, a.denominator) ** b
393d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
394d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if b.denominator == 1:
395d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return a ** b.numerator
396d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
397d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return a ** float(b)
398d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
399d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __pos__(a):
400d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """+a: Coerces a subclass instance to Rational"""
401d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return Rational(a.numerator, a.denominator)
402d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
403d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __neg__(a):
404d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """-a"""
405d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return Rational(-a.numerator, a.denominator)
406d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
407d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __abs__(a):
408d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """abs(a)"""
409d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return Rational(abs(a.numerator), a.denominator)
410d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
411d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __trunc__(a):
412d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """trunc(a)"""
413d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if a.numerator < 0:
414d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return -(-a.numerator // a.denominator)
415d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        else:
416d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return a.numerator // a.denominator
417d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
4185b0e27e50d33f33515f31ff6fec123f5e2be9d73Raymond Hettinger    __int__ = __trunc__
4195b0e27e50d33f33515f31ff6fec123f5e2be9d73Raymond Hettinger
420d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __hash__(self):
421d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """hash(self)
422d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
423d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        Tricky because values that are exactly representable as a
424d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        float must have the same hash as that float.
425d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
426d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """
427921cb5d3a3e823c6c225681d8e99f7baa8920f3eRaymond Hettinger        # XXX since this method is expensive, consider caching the result
428d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if self.denominator == 1:
429d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # Get integers right.
430d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return hash(self.numerator)
431d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        # Expensive check, but definitely correct.
432d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if self == float(self):
433d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return hash(float(self))
434d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        else:
435d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # Use tuple's hash to avoid a high collision rate on
436d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # simple fractions.
437d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return hash((self.numerator, self.denominator))
438d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
439d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __eq__(a, b):
440d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a == b"""
441d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if isinstance(b, RationalAbc):
442d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return (a.numerator == b.numerator and
443d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin                    a.denominator == b.denominator)
444d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if isinstance(b, numbers.Complex) and b.imag == 0:
445d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            b = b.real
446d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if isinstance(b, float):
447d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return a == a.from_float(b)
448d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        else:
449d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # XXX: If b.__eq__ is implemented like this method, it may
450d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # give the wrong answer after float(a) changes a's
451d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # value. Better ways of doing this are welcome.
452d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return float(a) == b
453d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
454d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def _subtractAndCompareToZero(a, b, op):
455d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """Helper function for comparison operators.
456d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
457d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        Subtracts b from a, exactly if possible, and compares the
458d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        result with 0 using op, in such a way that the comparison
459d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        won't recurse. If the difference raises a TypeError, returns
460d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        NotImplemented instead.
461d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
462d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """
463d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if isinstance(b, numbers.Complex) and b.imag == 0:
464d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            b = b.real
465d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if isinstance(b, float):
466d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            b = a.from_float(b)
467d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        try:
468d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # XXX: If b <: Real but not <: RationalAbc, this is likely
469d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # to fall back to a float. If the actual values differ by
470d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # less than MIN_FLOAT, this could falsely call them equal,
471d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # which would make <= inconsistent with ==. Better ways of
472d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            # doing this are welcome.
473d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            diff = a - b
474d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        except TypeError:
475d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return NotImplemented
476d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        if isinstance(diff, RationalAbc):
477d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin            return op(diff.numerator, 0)
478d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return op(diff, 0)
479d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
480d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __lt__(a, b):
481d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a < b"""
482d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return a._subtractAndCompareToZero(b, operator.lt)
483d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
484d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __gt__(a, b):
485d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a > b"""
486d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return a._subtractAndCompareToZero(b, operator.gt)
487d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
488d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __le__(a, b):
489d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a <= b"""
490d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return a._subtractAndCompareToZero(b, operator.le)
491d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
492d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __ge__(a, b):
493d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a >= b"""
494d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return a._subtractAndCompareToZero(b, operator.ge)
495d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin
496d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin    def __nonzero__(a):
497d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        """a != 0"""
498d7b00334f3cbf7a802e875238b9f2bd95e190436Jeffrey Yasskin        return a.numerator != 0
499a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger
500a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger    # support for pickling, copy, and deepcopy
501a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger
502a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger    def __reduce__(self):
503a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger        return (self.__class__, (str(self),))
504a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger
505a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger    def __copy__(self):
506a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger        if type(self) == Rational:
507a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger            return self     # I'm immutable; therefore I am my own clone
508a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger        return self.__class__(self.numerator, self.denominator)
509a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger
510a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger    def __deepcopy__(self, memo):
511a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger        if type(self) == Rational:
512a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger            return self     # My components are also immutable
513a6216749fb88fb508cd469839d77d4264a881bd4Raymond Hettinger        return self.__class__(self.numerator, self.denominator)
514