Python, простейший:
def a(n):
if n == 0: return 1
return 1 - 1 / float(a(n-1) + 3)
# limit is sqrt(3) - 1
limit = 3.0 ** 0.5 - 1.0
# get 9 digits' precision
i = 0
while abs(a(i) - limit) > 1.0e-9:
i += 1
print i
Это выдает 8
, предполагая, что оптимизация, такая как устранение рекурсии или запоминание, вероятно, не оправдана.
Конечно, обычно мы хотели бы получить предел численно, а не аналитически, поэтому обычный способ зацикливания будет несколько другим - и лучше всего инкапсулировать в функцию более высокого порядка ...:
# get a function's limit numerically
def limit(f, eps=1.0e-11):
previous_value = f(0)
next_value = f(1)
i = 2
while abs(next_value - previous_value) > eps:
previous_value = next_value
next_value = f(i)
i += 1
return next_value
Нетривиальная циклическая логика обычно лучше всего заключена в генераторе:
def next_prev(f):
previous_value = f(0)
i = 1
while True:
next_value = f(i)
yield next_value, previous_value
i += 1
previous_value = next_value
с помощью этого генератора limit
HOF становится намного проще:
def limit(f, eps=1.0e-11):
for next_value, previous_value in next_prev(f):
if abs(next_value - previous_value) < eps:
return next_value
Обратите внимание, насколько полезным является разделение: next_prev
воплощает концепцию «получить следующее и предыдущее значение функции», limit
просто имеет дело с «когда должен завершиться цикл».
И последнее, но не менее важное: itertools часто предлагает хорошую альтернативу генераторам, позволяя быстро инкапсулировать ограниченную логику итерации (хотя для этого нужно привыкнуть ...; -):
import itertools
def next_prev(f):
values = itertools.imap(f, itertools.count())
prv, nxt = itertools.tee(values)
nxt.next()
return itertools.izip(prv, nxt)