mirror of
https://github.com/python/cpython.git
synced 2025-11-29 14:31:30 +00:00
Minor optimization for Fractions.limit_denominator (GH-93730)
When we construct the upper and lower candidates in limit_denominator, the numerator and denominator are already relatively prime (and the denominator positive) by construction, so there's no need to go through the usual normalisation in the constructor. This saves a couple of potentially expensive gcd calls. Suggested by Michael Scott Asato Cuthbert in GH-93477.
This commit is contained in:
parent
830513754d
commit
420f0df862
1 changed files with 8 additions and 6 deletions
|
|
@ -245,14 +245,16 @@ class Fraction(numbers.Rational):
|
||||||
break
|
break
|
||||||
p0, q0, p1, q1 = p1, q1, p0+a*p1, q2
|
p0, q0, p1, q1 = p1, q1, p0+a*p1, q2
|
||||||
n, d = d, n-a*d
|
n, d = d, n-a*d
|
||||||
|
|
||||||
k = (max_denominator-q0)//q1
|
k = (max_denominator-q0)//q1
|
||||||
bound1 = Fraction(p0+k*p1, q0+k*q1)
|
|
||||||
bound2 = Fraction(p1, q1)
|
# Determine which of the candidates (p0+k*p1)/(q0+k*q1) and p1/q1 is
|
||||||
if abs(bound2 - self) <= abs(bound1-self):
|
# closer to self. The distance between them is 1/(q1*(q0+k*q1)), while
|
||||||
return bound2
|
# 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(p1, q1, _normalize=False)
|
||||||
else:
|
else:
|
||||||
return bound1
|
return Fraction(p0+k*p1, q0+k*q1, _normalize=False)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def numerator(a):
|
def numerator(a):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue