• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Originally contributed by Sjoerd Mullender.
2# Significantly modified by Jeffrey Yasskin <jyasskin at gmail.com>.
3
4"""Rational, infinite-precision, real numbers."""
5
6from __future__ import division
7from decimal import Decimal
8import math
9import numbers
10import operator
11import re
12
13__all__ = ['Fraction', 'gcd']
14
15Rational = numbers.Rational
16
17
18def gcd(a, b):
19    """Calculate the Greatest Common Divisor of a and b.
20
21    Unless b==0, the result will have the same sign as b (so that when
22    b is divided by it, the result comes out positive).
23    """
24    while b:
25        a, b = b, a%b
26    return a
27
28
29_RATIONAL_FORMAT = re.compile(r"""
30    \A\s*                      # optional whitespace at the start, then
31    (?P<sign>[-+]?)            # an optional sign, then
32    (?=\d|\.\d)                # lookahead for digit or .digit
33    (?P<num>\d*)               # numerator (possibly empty)
34    (?:                        # followed by
35       (?:/(?P<denom>\d+))?    # an optional denominator
36    |                          # or
37       (?:\.(?P<decimal>\d*))? # an optional fractional part
38       (?:E(?P<exp>[-+]?\d+))? # and optional exponent
39    )
40    \s*\Z                      # and optional whitespace to finish
41""", re.VERBOSE | re.IGNORECASE)
42
43
44class Fraction(Rational):
45    """This class implements rational numbers.
46
47    In the two-argument form of the constructor, Fraction(8, 6) will
48    produce a rational number equivalent to 4/3. Both arguments must
49    be Rational. The numerator defaults to 0 and the denominator
50    defaults to 1 so that Fraction(3) == 3 and Fraction() == 0.
51
52    Fractions can also be constructed from:
53
54      - numeric strings similar to those accepted by the
55        float constructor (for example, '-2.3' or '1e10')
56
57      - strings of the form '123/456'
58
59      - float and Decimal instances
60
61      - other Rational instances (including integers)
62
63    """
64
65    __slots__ = ('_numerator', '_denominator')
66
67    # We're immutable, so use __new__ not __init__
68    def __new__(cls, numerator=0, denominator=None):
69        """Constructs a Fraction.
70
71        Takes a string like '3/2' or '1.5', another Rational instance, a
72        numerator/denominator pair, or a float.
73
74        Examples
75        --------
76
77        >>> Fraction(10, -8)
78        Fraction(-5, 4)
79        >>> Fraction(Fraction(1, 7), 5)
80        Fraction(1, 35)
81        >>> Fraction(Fraction(1, 7), Fraction(2, 3))
82        Fraction(3, 14)
83        >>> Fraction('314')
84        Fraction(314, 1)
85        >>> Fraction('-35/4')
86        Fraction(-35, 4)
87        >>> Fraction('3.1415') # conversion from numeric string
88        Fraction(6283, 2000)
89        >>> Fraction('-47e-2') # string may include a decimal exponent
90        Fraction(-47, 100)
91        >>> Fraction(1.47)  # direct construction from float (exact conversion)
92        Fraction(6620291452234629, 4503599627370496)
93        >>> Fraction(2.25)
94        Fraction(9, 4)
95        >>> Fraction(Decimal('1.47'))
96        Fraction(147, 100)
97
98        """
99        self = super(Fraction, cls).__new__(cls)
100
101        if denominator is None:
102            if isinstance(numerator, Rational):
103                self._numerator = numerator.numerator
104                self._denominator = numerator.denominator
105                return self
106
107            elif isinstance(numerator, float):
108                # Exact conversion from float
109                value = Fraction.from_float(numerator)
110                self._numerator = value._numerator
111                self._denominator = value._denominator
112                return self
113
114            elif isinstance(numerator, Decimal):
115                value = Fraction.from_decimal(numerator)
116                self._numerator = value._numerator
117                self._denominator = value._denominator
118                return self
119
120            elif isinstance(numerator, basestring):
121                # Handle construction from strings.
122                m = _RATIONAL_FORMAT.match(numerator)
123                if m is None:
124                    raise ValueError('Invalid literal for Fraction: %r' %
125                                     numerator)
126                numerator = int(m.group('num') or '0')
127                denom = m.group('denom')
128                if denom:
129                    denominator = int(denom)
130                else:
131                    denominator = 1
132                    decimal = m.group('decimal')
133                    if decimal:
134                        scale = 10**len(decimal)
135                        numerator = numerator * scale + int(decimal)
136                        denominator *= scale
137                    exp = m.group('exp')
138                    if exp:
139                        exp = int(exp)
140                        if exp >= 0:
141                            numerator *= 10**exp
142                        else:
143                            denominator *= 10**-exp
144                if m.group('sign') == '-':
145                    numerator = -numerator
146
147            else:
148                raise TypeError("argument should be a string "
149                                "or a Rational instance")
150
151        elif (isinstance(numerator, Rational) and
152            isinstance(denominator, Rational)):
153            numerator, denominator = (
154                numerator.numerator * denominator.denominator,
155                denominator.numerator * numerator.denominator
156                )
157        else:
158            raise TypeError("both arguments should be "
159                            "Rational instances")
160
161        if denominator == 0:
162            raise ZeroDivisionError('Fraction(%s, 0)' % numerator)
163        g = gcd(numerator, denominator)
164        self._numerator = numerator // g
165        self._denominator = denominator // g
166        return self
167
168    @classmethod
169    def from_float(cls, f):
170        """Converts a finite float to a rational number, exactly.
171
172        Beware that Fraction.from_float(0.3) != Fraction(3, 10).
173
174        """
175        if isinstance(f, numbers.Integral):
176            return cls(f)
177        elif not isinstance(f, float):
178            raise TypeError("%s.from_float() only takes floats, not %r (%s)" %
179                            (cls.__name__, f, type(f).__name__))
180        if math.isnan(f) or math.isinf(f):
181            raise TypeError("Cannot convert %r to %s." % (f, cls.__name__))
182        return cls(*f.as_integer_ratio())
183
184    @classmethod
185    def from_decimal(cls, dec):
186        """Converts a finite Decimal instance to a rational number, exactly."""
187        from decimal import Decimal
188        if isinstance(dec, numbers.Integral):
189            dec = Decimal(int(dec))
190        elif not isinstance(dec, Decimal):
191            raise TypeError(
192                "%s.from_decimal() only takes Decimals, not %r (%s)" %
193                (cls.__name__, dec, type(dec).__name__))
194        if not dec.is_finite():
195            # Catches infinities and nans.
196            raise TypeError("Cannot convert %s to %s." % (dec, cls.__name__))
197        sign, digits, exp = dec.as_tuple()
198        digits = int(''.join(map(str, digits)))
199        if sign:
200            digits = -digits
201        if exp >= 0:
202            return cls(digits * 10 ** exp)
203        else:
204            return cls(digits, 10 ** -exp)
205
206    def limit_denominator(self, max_denominator=1000000):
207        """Closest Fraction to self with denominator at most max_denominator.
208
209        >>> Fraction('3.141592653589793').limit_denominator(10)
210        Fraction(22, 7)
211        >>> Fraction('3.141592653589793').limit_denominator(100)
212        Fraction(311, 99)
213        >>> Fraction(4321, 8765).limit_denominator(10000)
214        Fraction(4321, 8765)
215
216        """
217        # Algorithm notes: For any real number x, define a *best upper
218        # approximation* to x to be a rational number p/q such that:
219        #
220        #   (1) p/q >= x, and
221        #   (2) if p/q > r/s >= x then s > q, for any rational r/s.
222        #
223        # Define *best lower approximation* similarly.  Then it can be
224        # proved that a rational number is a best upper or lower
225        # approximation to x if, and only if, it is a convergent or
226        # semiconvergent of the (unique shortest) continued fraction
227        # associated to x.
228        #
229        # To find a best rational approximation with denominator <= M,
230        # we find the best upper and lower approximations with
231        # denominator <= M and take whichever of these is closer to x.
232        # In the event of a tie, the bound with smaller denominator is
233        # chosen.  If both denominators are equal (which can happen
234        # only when max_denominator == 1 and self is midway between
235        # two integers) the lower bound---i.e., the floor of self, is
236        # taken.
237
238        if max_denominator < 1:
239            raise ValueError("max_denominator should be at least 1")
240        if self._denominator <= max_denominator:
241            return Fraction(self)
242
243        p0, q0, p1, q1 = 0, 1, 1, 0
244        n, d = self._numerator, self._denominator
245        while True:
246            a = n//d
247            q2 = q0+a*q1
248            if q2 > max_denominator:
249                break
250            p0, q0, p1, q1 = p1, q1, p0+a*p1, q2
251            n, d = d, n-a*d
252
253        k = (max_denominator-q0)//q1
254        bound1 = Fraction(p0+k*p1, q0+k*q1)
255        bound2 = Fraction(p1, q1)
256        if abs(bound2 - self) <= abs(bound1-self):
257            return bound2
258        else:
259            return bound1
260
261    @property
262    def numerator(a):
263        return a._numerator
264
265    @property
266    def denominator(a):
267        return a._denominator
268
269    def __repr__(self):
270        """repr(self)"""
271        return ('Fraction(%s, %s)' % (self._numerator, self._denominator))
272
273    def __str__(self):
274        """str(self)"""
275        if self._denominator == 1:
276            return str(self._numerator)
277        else:
278            return '%s/%s' % (self._numerator, self._denominator)
279
280    def _operator_fallbacks(monomorphic_operator, fallback_operator):
281        """Generates forward and reverse operators given a purely-rational
282        operator and a function from the operator module.
283
284        Use this like:
285        __op__, __rop__ = _operator_fallbacks(just_rational_op, operator.op)
286
287        In general, we want to implement the arithmetic operations so
288        that mixed-mode operations either call an implementation whose
289        author knew about the types of both arguments, or convert both
290        to the nearest built in type and do the operation there. In
291        Fraction, that means that we define __add__ and __radd__ as:
292
293            def __add__(self, other):
294                # Both types have numerators/denominator attributes,
295                # so do the operation directly
296                if isinstance(other, (int, long, Fraction)):
297                    return Fraction(self.numerator * other.denominator +
298                                    other.numerator * self.denominator,
299                                    self.denominator * other.denominator)
300                # float and complex don't have those operations, but we
301                # know about those types, so special case them.
302                elif isinstance(other, float):
303                    return float(self) + other
304                elif isinstance(other, complex):
305                    return complex(self) + other
306                # Let the other type take over.
307                return NotImplemented
308
309            def __radd__(self, other):
310                # radd handles more types than add because there's
311                # nothing left to fall back to.
312                if isinstance(other, Rational):
313                    return Fraction(self.numerator * other.denominator +
314                                    other.numerator * self.denominator,
315                                    self.denominator * other.denominator)
316                elif isinstance(other, Real):
317                    return float(other) + float(self)
318                elif isinstance(other, Complex):
319                    return complex(other) + complex(self)
320                return NotImplemented
321
322
323        There are 5 different cases for a mixed-type addition on
324        Fraction. I'll refer to all of the above code that doesn't
325        refer to Fraction, float, or complex as "boilerplate". 'r'
326        will be an instance of Fraction, which is a subtype of
327        Rational (r : Fraction <: Rational), and b : B <:
328        Complex. The first three involve 'r + b':
329
330            1. If B <: Fraction, int, float, or complex, we handle
331               that specially, and all is well.
332            2. If Fraction falls back to the boilerplate code, and it
333               were to return a value from __add__, we'd miss the
334               possibility that B defines a more intelligent __radd__,
335               so the boilerplate should return NotImplemented from
336               __add__. In particular, we don't handle Rational
337               here, even though we could get an exact answer, in case
338               the other type wants to do something special.
339            3. If B <: Fraction, Python tries B.__radd__ before
340               Fraction.__add__. This is ok, because it was
341               implemented with knowledge of Fraction, so it can
342               handle those instances before delegating to Real or
343               Complex.
344
345        The next two situations describe 'b + r'. We assume that b
346        didn't know about Fraction in its implementation, and that it
347        uses similar boilerplate code:
348
349            4. If B <: Rational, then __radd_ converts both to the
350               builtin rational type (hey look, that's us) and
351               proceeds.
352            5. Otherwise, __radd__ tries to find the nearest common
353               base ABC, and fall back to its builtin type. Since this
354               class doesn't subclass a concrete type, there's no
355               implementation to fall back to, so we need to try as
356               hard as possible to return an actual value, or the user
357               will get a TypeError.
358
359        """
360        def forward(a, b):
361            if isinstance(b, (int, long, Fraction)):
362                return monomorphic_operator(a, b)
363            elif isinstance(b, float):
364                return fallback_operator(float(a), b)
365            elif isinstance(b, complex):
366                return fallback_operator(complex(a), b)
367            else:
368                return NotImplemented
369        forward.__name__ = '__' + fallback_operator.__name__ + '__'
370        forward.__doc__ = monomorphic_operator.__doc__
371
372        def reverse(b, a):
373            if isinstance(a, Rational):
374                # Includes ints.
375                return monomorphic_operator(a, b)
376            elif isinstance(a, numbers.Real):
377                return fallback_operator(float(a), float(b))
378            elif isinstance(a, numbers.Complex):
379                return fallback_operator(complex(a), complex(b))
380            else:
381                return NotImplemented
382        reverse.__name__ = '__r' + fallback_operator.__name__ + '__'
383        reverse.__doc__ = monomorphic_operator.__doc__
384
385        return forward, reverse
386
387    def _add(a, b):
388        """a + b"""
389        return Fraction(a.numerator * b.denominator +
390                        b.numerator * a.denominator,
391                        a.denominator * b.denominator)
392
393    __add__, __radd__ = _operator_fallbacks(_add, operator.add)
394
395    def _sub(a, b):
396        """a - b"""
397        return Fraction(a.numerator * b.denominator -
398                        b.numerator * a.denominator,
399                        a.denominator * b.denominator)
400
401    __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub)
402
403    def _mul(a, b):
404        """a * b"""
405        return Fraction(a.numerator * b.numerator, a.denominator * b.denominator)
406
407    __mul__, __rmul__ = _operator_fallbacks(_mul, operator.mul)
408
409    def _div(a, b):
410        """a / b"""
411        return Fraction(a.numerator * b.denominator,
412                        a.denominator * b.numerator)
413
414    __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv)
415    __div__, __rdiv__ = _operator_fallbacks(_div, operator.div)
416
417    def __floordiv__(a, b):
418        """a // b"""
419        # Will be math.floor(a / b) in 3.0.
420        div = a / b
421        if isinstance(div, Rational):
422            # trunc(math.floor(div)) doesn't work if the rational is
423            # more precise than a float because the intermediate
424            # rounding may cross an integer boundary.
425            return div.numerator // div.denominator
426        else:
427            return math.floor(div)
428
429    def __rfloordiv__(b, a):
430        """a // b"""
431        # Will be math.floor(a / b) in 3.0.
432        div = a / b
433        if isinstance(div, Rational):
434            # trunc(math.floor(div)) doesn't work if the rational is
435            # more precise than a float because the intermediate
436            # rounding may cross an integer boundary.
437            return div.numerator // div.denominator
438        else:
439            return math.floor(div)
440
441    def __mod__(a, b):
442        """a % b"""
443        div = a // b
444        return a - b * div
445
446    def __rmod__(b, a):
447        """a % b"""
448        div = a // b
449        return a - b * div
450
451    def __pow__(a, b):
452        """a ** b
453
454        If b is not an integer, the result will be a float or complex
455        since roots are generally irrational. If b is an integer, the
456        result will be rational.
457
458        """
459        if isinstance(b, Rational):
460            if b.denominator == 1:
461                power = b.numerator
462                if power >= 0:
463                    return Fraction(a._numerator ** power,
464                                    a._denominator ** power)
465                else:
466                    return Fraction(a._denominator ** -power,
467                                    a._numerator ** -power)
468            else:
469                # A fractional power will generally produce an
470                # irrational number.
471                return float(a) ** float(b)
472        else:
473            return float(a) ** b
474
475    def __rpow__(b, a):
476        """a ** b"""
477        if b._denominator == 1 and b._numerator >= 0:
478            # If a is an int, keep it that way if possible.
479            return a ** b._numerator
480
481        if isinstance(a, Rational):
482            return Fraction(a.numerator, a.denominator) ** b
483
484        if b._denominator == 1:
485            return a ** b._numerator
486
487        return a ** float(b)
488
489    def __pos__(a):
490        """+a: Coerces a subclass instance to Fraction"""
491        return Fraction(a._numerator, a._denominator)
492
493    def __neg__(a):
494        """-a"""
495        return Fraction(-a._numerator, a._denominator)
496
497    def __abs__(a):
498        """abs(a)"""
499        return Fraction(abs(a._numerator), a._denominator)
500
501    def __trunc__(a):
502        """trunc(a)"""
503        if a._numerator < 0:
504            return -(-a._numerator // a._denominator)
505        else:
506            return a._numerator // a._denominator
507
508    def __hash__(self):
509        """hash(self)
510
511        Tricky because values that are exactly representable as a
512        float must have the same hash as that float.
513
514        """
515        # XXX since this method is expensive, consider caching the result
516        if self._denominator == 1:
517            # Get integers right.
518            return hash(self._numerator)
519        # Expensive check, but definitely correct.
520        if self == float(self):
521            return hash(float(self))
522        else:
523            # Use tuple's hash to avoid a high collision rate on
524            # simple fractions.
525            return hash((self._numerator, self._denominator))
526
527    def __eq__(a, b):
528        """a == b"""
529        if isinstance(b, Rational):
530            return (a._numerator == b.numerator and
531                    a._denominator == b.denominator)
532        if isinstance(b, numbers.Complex) and b.imag == 0:
533            b = b.real
534        if isinstance(b, float):
535            if math.isnan(b) or math.isinf(b):
536                # comparisons with an infinity or nan should behave in
537                # the same way for any finite a, so treat a as zero.
538                return 0.0 == b
539            else:
540                return a == a.from_float(b)
541        else:
542            # Since a doesn't know how to compare with b, let's give b
543            # a chance to compare itself with a.
544            return NotImplemented
545
546    def _richcmp(self, other, op):
547        """Helper for comparison operators, for internal use only.
548
549        Implement comparison between a Rational instance `self`, and
550        either another Rational instance or a float `other`.  If
551        `other` is not a Rational instance or a float, return
552        NotImplemented. `op` should be one of the six standard
553        comparison operators.
554
555        """
556        # convert other to a Rational instance where reasonable.
557        if isinstance(other, Rational):
558            return op(self._numerator * other.denominator,
559                      self._denominator * other.numerator)
560        # comparisons with complex should raise a TypeError, for consistency
561        # with int<->complex, float<->complex, and complex<->complex comparisons.
562        if isinstance(other, complex):
563            raise TypeError("no ordering relation is defined for complex numbers")
564        if isinstance(other, float):
565            if math.isnan(other) or math.isinf(other):
566                return op(0.0, other)
567            else:
568                return op(self, self.from_float(other))
569        else:
570            return NotImplemented
571
572    def __lt__(a, b):
573        """a < b"""
574        return a._richcmp(b, operator.lt)
575
576    def __gt__(a, b):
577        """a > b"""
578        return a._richcmp(b, operator.gt)
579
580    def __le__(a, b):
581        """a <= b"""
582        return a._richcmp(b, operator.le)
583
584    def __ge__(a, b):
585        """a >= b"""
586        return a._richcmp(b, operator.ge)
587
588    def __nonzero__(a):
589        """a != 0"""
590        return a._numerator != 0
591
592    # support for pickling, copy, and deepcopy
593
594    def __reduce__(self):
595        return (self.__class__, (str(self),))
596
597    def __copy__(self):
598        if type(self) == Fraction:
599            return self     # I'm immutable; therefore I am my own clone
600        return self.__class__(self._numerator, self._denominator)
601
602    def __deepcopy__(self, memo):
603        if type(self) == Fraction:
604            return self     # My components are also immutable
605        return self.__class__(self._numerator, self._denominator)
606