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