Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.7k
gh-101773: Optimize creation of Fractions in private methods#101780
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes from1 commit
9cc62f7836d3a63625d349e66b5a4324391b0dca383a8506d13262af4e8977a57ac3734b4a386580b1be53d5e94File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
- Loading branch information
Uh oh!
There was an error while loading.Please reload this page.
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -183,7 +183,7 @@ class Fraction(numbers.Rational): | ||
| __slots__ = ('_numerator', '_denominator') | ||
| # We're immutable, so use __new__ not __init__ | ||
| def __new__(cls, numerator=0, denominator=None): | ||
skirpichev marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| """Constructs a Rational. | ||
| Takes a string like '3/2' or '1.5', another Rational instance, a | ||
| @@ -279,12 +279,11 @@ def __new__(cls, numerator=0, denominator=None, *, _normalize=True): | ||
| if denominator == 0: | ||
| raise ZeroDivisionError('Fraction(%s, 0)' % numerator) | ||
| g = math.gcd(numerator, denominator) | ||
| if denominator < 0: | ||
| g = -g | ||
| numerator //= g | ||
| denominator //= g | ||
| self._numerator = numerator | ||
| self._denominator = denominator | ||
| return self | ||
| @@ -315,6 +314,13 @@ def from_decimal(cls, dec): | ||
| (cls.__name__, dec, type(dec).__name__)) | ||
| return cls(*dec.as_integer_ratio()) | ||
| @classmethod | ||
| def _from_pair(cls, num, den): | ||
skirpichev marked this conversation as resolved. OutdatedShow resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| obj = super(Fraction, cls).__new__(cls) | ||
| obj._numerator = num | ||
| obj._denominator = den | ||
| return obj | ||
| def is_integer(self): | ||
| """Return True if the Fraction is an integer.""" | ||
| return self._denominator == 1 | ||
| @@ -380,9 +386,9 @@ def limit_denominator(self, max_denominator=1000000): | ||
| # the distance from p1/q1 to self is d/(q1*self._denominator). So we | ||
| # need to compare 2*(q0+k*q1) with self._denominator/d. | ||
| if 2*d*(q0+k*q1) <= self._denominator: | ||
| return Fraction._from_pair(p1, q1) | ||
| else: | ||
| return Fraction._from_pair(p0+k*p1, q0+k*q1) | ||
| @property | ||
| def numerator(a): | ||
| @@ -703,13 +709,13 @@ def _add(a, b): | ||
| nb, db = b._numerator, b._denominator | ||
| g = math.gcd(da, db) | ||
| if g == 1: | ||
| return Fraction._from_pair(na * db + da * nb, da * db) | ||
| s = da // g | ||
| t = na * (db // g) + nb * s | ||
| g2 = math.gcd(t, g) | ||
| if g2 == 1: | ||
| return Fraction._from_pair(t, s * db) | ||
| return Fraction._from_pair(t // g2, s * (db // g2)) | ||
| __add__, __radd__ = _operator_fallbacks(_add, operator.add) | ||
| @@ -719,13 +725,13 @@ def _sub(a, b): | ||
| nb, db = b._numerator, b._denominator | ||
| g = math.gcd(da, db) | ||
| if g == 1: | ||
| return Fraction._from_pair(na * db - da * nb, da * db) | ||
| s = da // g | ||
| t = na * (db // g) - nb * s | ||
| g2 = math.gcd(t, g) | ||
| if g2 == 1: | ||
| return Fraction._from_pair(t, s * db) | ||
| return Fraction._from_pair(t // g2, s * (db // g2)) | ||
| __sub__, __rsub__ = _operator_fallbacks(_sub, operator.sub) | ||
| @@ -741,15 +747,17 @@ def _mul(a, b): | ||
| if g2 > 1: | ||
| nb //= g2 | ||
| da //= g2 | ||
| return Fraction._from_pair(na * nb, db * da) | ||
| __mul__, __rmul__ = _operator_fallbacks(_mul, operator.mul) | ||
| def _div(a, b): | ||
| """a / b""" | ||
| # Same as _mul(), with inversed b. | ||
| nb, db = b._numerator, b._denominator | ||
| if nb == 0: | ||
| raise ZeroDivisionError('Fraction(%s, 0)' % db) | ||
skirpichev marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| na, da = a._numerator, a._denominator | ||
| g1 = math.gcd(na, nb) | ||
| if g1 > 1: | ||
| na //= g1 | ||
| @@ -761,7 +769,7 @@ def _div(a, b): | ||
| n, d = na * db, nb * da | ||
| if d < 0: | ||
| n, d = -n, -d | ||
| return Fraction._from_pair(n, d) | ||
| __truediv__, __rtruediv__ = _operator_fallbacks(_div, operator.truediv) | ||
| @@ -798,17 +806,17 @@ def __pow__(a, b): | ||
| if b.denominator == 1: | ||
| power = b.numerator | ||
| if power >= 0: | ||
| return Fraction._from_pair(a._numerator ** power, | ||
| a._denominator ** power) | ||
| elif a._numerator > 0: | ||
| return Fraction._from_pair(a._denominator ** -power, | ||
| a._numerator ** -power) | ||
| elif a._numerator == 0: | ||
| raise ZeroDivisionError('Fraction(%s, 0)' % | ||
skirpichev marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| a._denominator ** -power) | ||
| else: | ||
| return Fraction._from_pair((-a._denominator) ** -power, | ||
| (-a._numerator) ** -power) | ||
| else: | ||
| # A fractional power will generally produce an | ||
| # irrational number. | ||
| @@ -832,15 +840,15 @@ def __rpow__(b, a): | ||
| def __pos__(a): | ||
| """+a: Coerces a subclass instance to Fraction""" | ||
| return Fraction._from_pair(a._numerator, a._denominator) | ||
| def __neg__(a): | ||
| """-a""" | ||
| return Fraction._from_pair(-a._numerator, a._denominator) | ||
| def __abs__(a): | ||
| """abs(a)""" | ||
| return Fraction._from_pair(abs(a._numerator), a._denominator) | ||
skirpichev marked this conversation as resolved. OutdatedShow resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| def __int__(a, _index=operator.index): | ||
| """int(a)""" | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Optimize:class:`fractions.Fraction` for small components. | ||
skirpichev marked this conversation as resolved. OutdatedShow resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||