Код для генерации одной цифры за раз
Я пытаюсь создать постоянные генераторы случайных чисел (я имею в виду ГСЧ, которая выводит последовательность чисел, которая не повторяется, но остается неизменной каждый раз, когда она начинается с начала). У меня есть один для пи. Мне нужен алгоритм для генерации цифр за цифрой для подачи в ГСЧ, предпочтительно в форме итератора или генератора Python. Я также приветствую коды, которые генерируют другие иррациональные числа. Заранее спасибо.
4 ответа
Да! Я сделал это с продолженной дробью!
Я нашел этот код из Генерации цифр квадратного корня из 2
def z(contfrac, a=1, b=0, c=0, d=1):
for x in contfrac:
while a > 0 and b > 0 and c > 0 and d > 0:
t = a // c
t2 = b // d
if not t == t2:
break
yield t
a = (10 * (a - c*t))
b = (10 * (b - d*t))
# continue with same fraction, don't pull new x
a, b = x*a+b, a
c, d = x*c+d, c
for digit in rdigits(a, c):
yield digit
def rdigits(p, q):
while p > 0:
if p > q:
d = p // q
p = p - q * d
else:
d = (10 * p) // q
p = 10 * p - q * d
yield d
Я сделал генератор продолженной дроби:
def e_cf_expansion():
yield 1
k = 0
while True:
yield k
k += 2
yield 1
yield 1
и собрать их вместе:
def e_dec():
return z(e_cf_expansion())
Затем:
>>> gen = e_dec()
>>> e = [str(gen.next()) for i in xrange(1000)]
>>> e.insert(1, '.')
>>> print ''.join(e)
2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427427466391932003059921817413596629043572900334295260595630738132328627943490763233829880753195251019011573834187930702154089149934884167509244761460668082264800168477411853742345442437107539077744992069551702761838606261331384583000752044933826560297606737113200709328709127443747047230696977209310141692836819025515108657463772111252389784425056953696770785449969967946864454905987931636889230098793127736178215424999229576351482208269895193668033182528869398496465105820939239829488793320362509443117301238197068416140397019837679320683282376464804295311802328782509819455815301756717361332069811250996181881593041690351598888519345807273866738589422879228499892086805825749279610484198444363463244968487560233624827041978623209002160990235304369941849146314093431738143640546253152096183690888707016768396424378140592714563549061303107208510383750510115747704171898610687396965521267154688957035035
Бонус: код для генерации непрерывной дроби для sqrt(n), где n - положительное целое число, а sqrt(n) - иррационально:
def sqrt_cf_expansion(S):
"""Generalized generator to compute continued
fraction representation of sqrt(S)"""
m = 0
d = 1
a = int(math.sqrt(S))
a0 = a
while True:
yield a
m = d*a-m
d = (S-m**2)//d
a = (a0+m)//d
Если вы позвоните random.seed(n)
из random
модуль с известным n
результат будет одинаковым каждый раз:
>>> import random
>>> random.seed(4) # chosen by fair dice roll
>>> random.randint(0, 9)
2
>>> random.randint(0, 9)
1
>>> random.randint(0, 9)
3
>>> random.randint(0, 9)
1
>>> random.seed(4) # same seed as above
>>> random.randint(0, 9)
2
>>> random.randint(0, 9)
1
>>> random.randint(0, 9)
3
>>> random.randint(0, 9)
1
Если вам нужно передать состояние, используйте Random
класс (несколько недокументированный):
>>> r = random.Random(4)
>>> r.randint(0, 9)
2
>>> r.randint(0, 9)
1
Из этого легко сделать генератор, который позволяет создавать несколько последовательностей, которые не наступают друг на друга:
def random_digits(seed):
r = random.Random(seed)
while True:
yield r.randint(0, 9)
Возможно, вы ищете что-то вроде этого:
>>> import math
>>> i = 1
>>> while i < 10:
... print('e = {0:.{1}f}'.format(math.e, i))
... i += 1
...
e = 2.7
e = 2.72
e = 2.718
e = 2.7183
e = 2.71828
e = 2.718282
e = 2.7182818
e = 2.71828183
e = 2.718281828
Стандартная библиотека может дать вам math.e
: математическая константа e = 2.718281..., с доступной точностью.
Если вы хотите использовать пи вместо е, есть алгоритм извлечения цифр для пи. Неизвестно, существует ли такой алгоритм для e. Файл bbp_pi.py в sympy обеспечивает отличную реализацию алгоритма.