表示以下等式的最简单方法是什么?
为了澄清,我的问题是要求一些代码来计算方程的答案。
这有两个问题:
总和保证无限循环,无法从
我希望得到一个详尽的答案(可能是40位左右)。
答案 0 :(得分:5)
如果您需要更高的精确度,可以尝试使用Fraction
:
from fractions import Fraction # use rational numbers, they are more precise than floats
e = Fraction(0)
f = Fraction(1)
n = Fraction(1)
while True:
d = Fraction(1) / f # this ...
if d < Fraction(1, 10**40): # don't continue if the advancement is too small
break
e += d # ... and this are the formula you wrote for "e"
f *= n # calculate factorial incrementally, faster than calling "factorial()" all the time
n += Fraction(1) # we will use this for calculating the next factorial
print(float(e))
或Decimal
:
from decimal import Decimal, getcontext
getcontext().prec = 40 # set the precision to 40 places
e = Decimal(0)
f = Decimal(1)
n = Decimal(1)
while True:
olde = e
e += Decimal(1) / f
if e == olde: # if there was no change in the 40 places, stop.
break
f *= n
n += Decimal(1)
print(float(e))
所以这里是e
在1000个地方:
2.71828182845904523536028747135266249775724709369995957496696762772407663035354759457138217852516642742746639193200305992181741359662904357290033429526059563073813232862794349076323382988075319525101901157383418793070215408914993488416750924476146066808226480016847741185374234544243710753907774499206955170276183860626133138458300075204493382656029760673711320070932870912744374704723069697720931014169283681902551510865746377211125238978442505695369677078544996996794686445490598793163688923009879312773617821542499922957635148220826989519366803318252886939849646510582093923982948879332036250944311730123819706841614039701983767932068328237646480429531180232878250981945581530175671736133206981125099618188159304169035159888851934580727386673858942287922849989208680582574927961048419844436346324496848756023362482704197862320900216099023530436994184914631409343173814364054625315209618369088870701676839642437814059271456354906130310720851038375051011574770417189861068739696552126715468895703 5044
为了更清楚地了解它的作用,这里是它的简化版本:
e = f = 1.0
for i in range(2, 16):
e += 1.0 / f
f *= i
print(e)
答案 1 :(得分:3)
显而易见的解决方案是
import math
def e(n=10):
return sum(1 / float(math.factorial(i)) for i in range(n))
但它在n = 20附近失去了精度(与math.e相比误差大约为10 ^ -16)
40位精度可能是一个挑战,可能需要任意精度算术
我真的没有意识到有这样精确的&#34; e&#34;因为你不能以这样的精度执行任何计算(如果你对它做任何,你会失去那个精度,除非你用任意精度算术做所有事情)。< / p>
答案 2 :(得分:0)
为my answer from a question on approximating pi
生成类似的结果:
from functools import wraps
def memoize(f):
"""Store and retrive previous results of the decorated function f."""
cache = {}
@wraps(f)
def func(*args):
if args not in cache:
cache[args] = f(*args)
return cache[args]
return func
@memoize
def fact(n):
"""Recursively calculates n!."""
if n <= 1:
return 1
return n * fact(n - 1)
def inverse_fact_n(start_n=0):
"""Generator producing the infinite series 1/n!."""
numerator = 1.0
denominator = start_n
while True:
yield numerator / fact(denominator)
denominator += 1
def approximate_e(steps=None, tolerance=None):
"""Calculate an approximation of e from summation of 1/n!."""
if steps is None and tolerance is None:
raise ValueError("Must supply one of steps or tolerance.")
series = inverse_fact_n()
if steps is not None: # stepwise method
return sum(next(series) for _ in range(steps))
output = 0 # tolerance method
term = next(series)
while abs(term) > tolerance:
output += term
term = next(series)
return output
if __name__ == "__main__":
from math import e
print("math.e:\t\t{0:.20f}.".format(e))
stepwise = approximate_e(steps=100)
print("Stepwise:\t{0:.20f}.".format(stepwise))
tolerated = approximate_e(tolerance=0.0000000001)
print("Tolerated:\t{0:.20f}.".format(tolerated))
函数approximate_e
允许您指定:
steps
(&#34;我希望它花费这么长时间&#34;);或tolerance
(&#34;我希望它是准确的&#34;)。围绕这个有一些相对高级的Python(例如memoizing装饰器函数和生成系列的生成器函数),但你可以只专注于main函数,其中next(series)
为你提供下一个术语总和。
这给了我输出:
math.e: 2.71828182845904509080.
Stepwise: 2.71828182845904553488.
Tolerated: 2.71828182844675936281.
答案 3 :(得分:0)
最有效的方法是使用指数函数的属性。
exp(x)=(exp(x/N))^N
因此,你计算x = exp(2 ^( - n)),其精度比最终结果要求的精度高2n位,并通过将结果平方n次来计算e。
对于小数x,在幂m-1项下截断exp(x)系列的误差小于下一项幂m的两倍。
总而言之,为了以d位的精度/精度计算e,你选择一些中等大n并选择m以便
2^(1-mn)/m! is smaller than 2^(-d-2n)
m的确定也可以动态完成(使用Decimal,如用户22698的答案)
from decimal import Decimal, getcontext
def eulernumber(d):
dd=d
n=4
while dd > 1:
dd /= 8
n += 1
getcontext().prec = d+n
x = Decimal(1)/Decimal(1 << n)
eps = Decimal(1)/Decimal(1 << (1 + (10*d)/3 ))
term = x
expsum = Decimal(1) + x
m = 2
while term > eps:
term *= x / Decimal(m)
m += 1
expsum += term
for k in range(n):
expsum *= expsum
getcontext().prec = d
expsum += Decimal(0)
return expsum
if __name__ == "__main__":
for k in range(1,6):
print(k,eulernumber(4*k))
for k in range(10,13):
print(k,eulernumber(4*k))
带输出
( 1, Decimal('2.718'))
( 2, Decimal('2.7182818'))
( 3, Decimal('2.71828182846'))
( 4, Decimal('2.718281828459045'))
( 5, Decimal('2.7182818284590452354'))
(10, Decimal('2.718281828459045235360287471352662497757'))
(11, Decimal('2.7182818284590452353602874713526624977572471'))
(12, Decimal('2.71828182845904523536028747135266249775724709370'))
请参阅(unix / posix)bc数学库,以获得更专业的实现此思想,也可用于对数和触发函数。指数函数的代码甚至在手册页中作为示例给出。