Python函数近似e的数学值

时间:2016-01-29 15:05:25

标签: python math

我正在编写一个近似e的数学值的函数。

我们被告知使用上面的factorial函数和inverse函数。还建议使用map

到目前为止,我有这个,但它给我一个错误说:ValueError: factorial() only accepts integral values

def inverse(n):
    """Returns the inverse of n"""
    return 1 / n

def e(n):
    """Approximates the mathematical value e"""
    lst = range(1, n+1)
    lst2 = map(inverse, lst)
    lst3 = map(math.factorial, lst2)
    return sum(lst3)

有人能指出我正确的方向吗?

4 个答案:

答案 0 :(得分:1)

现在这对我有用。我需要将范围从(1, n+1)更改为(0, n+1)并反转先执行factorial然后执行inverse的顺序。

def inverse(n):
    """Returns the inverse of n"""
    return 1 / n


def e(n):
    """Approximates the mathematical value e"""
    lst = map(math.factorial, range(0, n+1))
    return sum(map(inverse, lst))

答案 1 :(得分:1)

e 可以用Σ(1 / k!)定义,其中k = 0..∞。

所以,对于每个k,

  1. 计算k!
  2. 转化
  3. 添加到总计
  4. 看起来你在阶乘之前而不是之后进行反演,从1而不是0开始。

    请注意,这不是执行此计算的最有效方法,因为不必为每个k从头开始计算阶乘。

答案 2 :(得分:0)

正如其他人所指出的那样:

  • 您缺少系列中的第一个词,即1。
  • 在python中,如果两个数字都是整数,则除法给出一个整数值。即1/2 == 0

你需要这样的东西:

def inverse(n):
    """Returns the inverse of n"""
    # Using 1 as a float makes the division return a float value.
    return 1. / n

def e(n):
    """Approximates the mathematical value e"""
    lst = range(1, n+1) # k=1...n
    lst2 = map(math.factorial, lst)
    return 1 + sum(map(inverse, lst2))

您可以将近似值与math.exp

进行比较
>>> abs(math.exp(1) - e(20)) < 1e-10
True

答案 3 :(得分:0)

我对这个问题很开心,使用生成器和装饰器。首先,您可以创建一个生成器yield连续更精确的e值:

def compute_e():
    currentFactorial = 1
    currentSum = 1
    for i in itertools.count(start=1):
        currentFactorial *= i
        currentSum += 1/currentFactorial
        yield currentSum

然后,我创建一个装饰器来找到一个固定点(具有最大迭代次数和所需精度):

def getFixedPoint(gen, maxiter=10000, precision=0):
    def mywrap(*args, **kwargs):
        instanceGen = gen(*args, **kwargs)
        prevValue = next(instanceGen)
        for n, value in enumerate(instanceGen):
            if (value - prevValue < precision) or (n > maxiter):
                return value
            else:
                prevValue = value
    return mywrap

给了我这样的东西:

In [83]: getFixedPoint(compute_e)()
Out[83]: 2.7182818284590455

In [84]: getFixedPoint(compute_e, maxiter=5)()
Out[84]: 2.71827876984127

In [85]: getFixedPoint(compute_e, precision = 0.001)()
Out[85]: 2.7182539682539684

现在,我可以改变计算e的每个连续值的方式,例如使用from decimal import Decimal

@getFixedPoint
def compute_e():
    currentFactorial = Decimal(1)
    currentSum = Decimal(1)
    for i in itertools.count(start=1):
        currentFactorial *= i
        currentSum += 1/currentFactorial
        yield currentSum

compute_e()
Out[95]: Decimal('2.718281828459045235360287474')