詳細な情報がなければ、 Wikipediaに示されているように、eの単純な連分数展開を使用するのがおそらく Good Idea™ です。
e = [2; 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8, 1, 1, 10, 1, 1, 12, 1, 1, ...]
このシーケンスは、単純なリスト内包表記を使用して簡単に作成できます。
単純な連分数展開を評価するために、リストを逆の順序で処理できます。
次のコードは、Python 2 または Python 3 で動作します。
#!/usr/bin/env python
''' Calculate e using its simple continued fraction expansion
See http://stackoverflow.com/q/36077810/4014959
Also see
https://en.wikipedia.org/wiki/Continued_fraction#Regular_patterns_in_continued_fractions
Written by PM 2Ring 2016.03.18
'''
from __future__ import print_function, division
import sys
def contfrac_to_frac(seq):
''' Convert the simple continued fraction in `seq`
into a fraction, num / den
'''
num, den = 1, 0
for u in reversed(seq):
num, den = den + num*u, num
return num, den
def e_cont_frac(n):
''' Build `n` terms of the simple continued fraction expansion of e
`n` must be a positive integer
'''
seq = [2 * (i+1) // 3 if i%3 == 2 else 1 for i in range(n)]
seq[0] += 1
return seq
def main():
# Get the the number of terms, less one
n = int(sys.argv[1]) if len(sys.argv) > 1 else 11
if n < 0:
print('Argument must be >= 0')
exit()
n += 1
seq = e_cont_frac(n)
num, den = contfrac_to_frac(seq)
print('Terms =', n)
print('Continued fraction:', seq)
print('Fraction: {0} / {1}'.format(num, den))
print('Float {0:0.15f}'.format(num / den))
if __name__ == '__main__':
main()
出力
Terms = 12
Continued fraction: [2, 1, 2, 1, 1, 4, 1, 1, 6, 1, 1, 8]
Fraction: 23225 / 8544
Float 2.718281835205993
プログラムに 20 の引数を渡して、Python 浮動小数点数を使用して可能な限り最適な近似値を取得します: 2.718281828459045
Rory Daulton (およびウィキペディア) が言及しているように、継続分数リストを逆にする必要はありません。順方向に処理できますが、2 世代の分子と分母を追跡する必要があるため、さらに 2 つの変数が必要です。これは、それを行うバージョンですcontfrac_to_frac
。
def contfrac_to_frac(seq):
''' Convert the simple continued fraction in `seq`
into a fraction, num / den
'''
n, d, num, den = 0, 1, 1, 0
for u in seq:
n, d, num, den = num, den, num*u + n, den*u + d
return num, den