diff --git a/Lib/fractions.py b/Lib/fractions.py index f9ac882ec002fa..ea7e5b8f18e296 100644 --- a/Lib/fractions.py +++ b/Lib/fractions.py @@ -238,6 +238,7 @@ def limit_denominator(self, max_denominator=1000000): p0, q0, p1, q1 = 0, 1, 1, 0 n, d = self._numerator, self._denominator + n_original, d_original = n, d while True: a = n//d q2 = q0+a*q1 @@ -247,12 +248,23 @@ def limit_denominator(self, max_denominator=1000000): n, d = d, n-a*d k = (max_denominator-q0)//q1 - bound1 = Fraction(p0+k*p1, q0+k*q1) - bound2 = Fraction(p1, q1) - if abs(bound2 - self) <= abs(bound1-self): - return bound2 + bound1_n = p0 + k*p1 + bound1_d = q0 + k*q1 + bound2_n = p1 + bound2_d = q1 + + # diff1_n = numerator of (bound1 minus self) as a Fraction; + # etc. for diff1_d, diff2_n, diff2_d + diff1_n = abs(bound1_n*d_original - n_original*bound1_d) + diff1_d = d_original * bound1_d + diff2_n = abs(bound2_n*d_original - n_original*bound2_d) + diff2_d = d_original * bound2_d + + if diff1_n * diff2_d >= diff2_n * diff1_d: + # bound2 is closer (or equal) to original as bound 1 + return Fraction(bound2_n, bound2_d, _normalize=False) else: - return bound1 + return Fraction(bound1_n, bound1_d, _normalize=False) @property def numerator(a): diff --git a/Misc/NEWS.d/next/Library/2022-06-03-11-17-49.gh-issue-93476.vvjcGL.rst b/Misc/NEWS.d/next/Library/2022-06-03-11-17-49.gh-issue-93476.vvjcGL.rst new file mode 100644 index 00000000000000..09298d31f47cdd --- /dev/null +++ b/Misc/NEWS.d/next/Library/2022-06-03-11-17-49.gh-issue-93476.vvjcGL.rst @@ -0,0 +1,2 @@ +:meth:`fractions.Fraction.limit_denominator()` performance enhancements. +Patch by Michael Scott Asato Cuthbert.