Wenn der Nenner von R
größer ist als m
dann die Farey-Methode anwenden (die die Fraction.limit_denominator
Methode implementiert) mit einer Grenze von m
um einen Bruch zu erhalten a/b
donde b
kleiner ist als m
sonst lassen a/b = R
. Mit b <= m
entweder a <= n
und Sie sind fertig, oder lassen Sie M = math.ceil(n/R)
und führen Sie die Farey-Methode erneut durch.
def approx2(a, b, n, m):
from math import ceil
from fractions import Fraction
R = Fraction(a, b)
if R < Fraction(1, m):
return 1, m
r = R.limit_denominator(m)
if r.numerator > n:
M = ceil(n/R)
r = R.limit_denominator(M)
return r.numerator, r.denominator
>>> approx2(113, 205, 50, 200)
(43, 78)
Es könnte möglich sein, die Farey-Methode nur einmal durchzuführen und dabei einen begrenzten Nenner von min(ceil(n/R), m)
aber ich bin mir da nicht sicher:
def approx(a, b, n, m):
from math import ceil
from fractions import Fraction
R = Fraction(a, b)
if R < Fraction(1, m):
return 1, m
r = R.limit_denominator(min(ceil(n/R), m))
return r.numerator, r.denominator