Python mpmath不是任意精度?

时间:2014-09-07 21:11:31

标签: python arbitrary-precision mpmath

我试图继续上一个问题,我试图用Benet算法计算斐波纳契数。为了处理任意精度,我找到了mpmath。然而,实施似乎失败超过一定的价值。例如,第99个值给出:

  

218922995834555891712

这应该是(ref):

  

218922995834555169026

这是我的代码:

from mpmath import *

def Phi():
    return (1 + sqrt(5)) / 2

def phi():
    return (1 - sqrt(5)) / 2

def F(n):
    return (power(Phi(), n) - power(phi(), n)) / sqrt(5)

start = 99
end = 100

for x in range(start, end):
    print(x, int(F(x)))

3 个答案:

答案 0 :(得分:2)

mpmath可以进行任意精度数学运算,如果使用任意精度数学模块而不是默认行为,它确实可以精确地达到任何精度(如上所述)。

mpmath有多个模块可以确定结果的准确性和速度(根据你的需要选择),默认情况下它使用Python浮点数,这是我相信你在上面看到的。

如果你打电话给mpmath< fib()设定了足够高的mp.dps,你将得到正确的答案。

>>> from mpmath import mp
>>> mp.dps = 25
>>> mp.nprint( mp.fib( 99 ), 25 )
218922995834555169026.0
>>> mp.nprint( mpmath.fib( 99 ), 25 )
218922995834555169026.0

然而,如果您不使用mp模块,您将只获得与Python double一样准确的结果。

>>> import mpmath
>>> mpmath.dps = 25
>>> mpmath.nprint( mpmath.fib( 99 ), 25
218922995834555170816.0

答案 1 :(得分:1)

mpmath提供任意精度(在mpmath.mp.dps中设置),但仍然是不准确的计算。例如,mpmath.sqrt(5)不准确,因此基于此的任何计算也都是不准确的。

要获得sqrt(5)的准确结果,您必须使用支持抽象计算的库,例如http://sympy.org/

为了获得Fibonacci数的准确结果,可能最简单的方法是使用只进行整数算术的算法。例如:

def fib(n):
  if n < 0:
    raise ValueError

  def fib_rec(n):
    if n == 0:
      return 0, 1
    else:
      a, b = fib_rec(n >> 1)
      c = a * ((b << 1) - a)
      d = b * b + a * a
      if n & 1:
        return d, c + d
      else:
        return c, d

  return fib_rec(n)[0]

答案 2 :(得分:0)

实际上mpmath的默认精度是15,我认为如果你想获得高达21位精度的结果是不够的。

您可以做的一件事是将精度设置为更高的值,并使用mpmath定义的算术函数进行加法,减法等。

    from mpmath import mp
    mp.dps = 50
    sqrt5 = mp.sqrt(5)
    def Phi():
        return 0.5*mp.fadd(1, sqrt5)

    def phi():
        return 0.5*mp.fsub(1, sqrt5)

    def F(n):
        return mp.fdiv(mp.power(Phi(), n) - mp.power(phi(), n), sqrt5)

    print int(F(99))

这会给你

    218922995834555169026L