Python在处理大浮点数和整数时防止溢出错误

时间:2014-05-11 01:09:28

标签: python optimization sequence fibonacci integer-overflow

我正在开发一个python程序,以计算Fibonacci序列中的数字。这是我的代码:

import math
def F(n):
    return ((1+math.sqrt(5))**n-(1-math.sqrt(5))**n)/(2**n*math.sqrt(5))
def fib(n):
    for i in range(n):
        print F(i)

我的代码使用此公式来查找Fibonacci序列中的第N个数字:

enter image description here

这可以计算Fibonacci序列中的许多数字,但我确实遇到溢出错误。

如何改进此代码并防止出现溢出错误?

注意:我使用的是python 2.7。

4 个答案:

答案 0 :(得分:0)

您对的陈述如何改进此代码... 有点模糊,所以我会将其视为缩短代码:

import math
def fib(j):
    for i in [int(((1+math.sqrt(5))**n-(1-math.sqrt(5))**n)/(2**n*math.sqrt(5))) for n in range(j)]: print i

您可以将两个函数组合成一个函数,并使用列表推导,您可以使该函数在一行中运行。

如果您使用的是非常大的数字,则无法阻止溢出错误,而是尝试捕获它们然后破坏:

import math
def fib(j):
        try:
                for i in [int(((1+math.sqrt(5))**n-(1-math.sqrt(5))**n)/(2**n*math.sqrt(5))) for n in range(j)]: print i
        except Exception as e:
                print 'There was an error, your number was too large!'

第二个将首先遍历所有内容并确保没有错误,如果没有,它将继续打印它。

答案 1 :(得分:0)

我不知道你是否接受这个,但你可以使用整数运算来计算使用递归关系的fib数(例如,F3 = F2 + F1)。

从Python 2.5开始,你可以进行任意精度整数运算 - 几乎可以消除溢出问题 - 如果你试图计算F(10000),它无疑会变得很慢。

另外,检查十进制模块 - IIRC正确,你可以使用Python 2.7,你可以指定十进制算术的精度 - 这将允许你继续使用相同的算法 - 除了使用小数类型。

ADDED

您可以轻易忽略十进制类包含平方根方法。您需要使用此方法而不是math.sqrt(),因为您需要保留十进制类的完整精度。

sqrt(5)也是一项相对昂贵的操作。只计算一次

答案 2 :(得分:0)

python double的值有限。但是int不会:

a,b,c=0,1,0

untill=int(raw_input("> "))

for i in range(0,untill):
    c=a+b
    print b
    a=b
    b=c

可以永远继续下去,但在找不到所有数字之前找不到N.

答案 3 :(得分:0)

Python的整数是任意精度的,因此如果使用交互算法计算斐波纳契数列,就可以计算出精确的结果。

>>> def fib(n):
...   a = 0
...   b = 1
...   while n > 0:
...     a, b = b, a + b
...     n = n - 1
...   return a
... 
>>> fib(100)
354224848179261915075L

Python有几个多精度浮点库。 decimal模块包含在Python中,最初用于财务计算。它支持sqrt(),因此您可以执行以下操作:

>>> import decimal
>>> decimal.setcontext(decimal.Context(prec=40))
>>> a=decimal.Decimal(5).sqrt()
>>> a
Decimal('2.236067977499789696409173668731276235441')
>>> ((1+a)**100 - (1-a)**100)/(a*(2**100))
Decimal('354224848179261915075.0000000000000000041')

其他图书馆是mpmathgmpy2

>>> import gmpy2
>>> gmpy2.set_context(gmpy2.context(precision=150))
>>> a=gmpy2.sqrt(5)
>>> a
mpfr('2.2360679774997896964091736687312762354406183598',150)
>>> ((1+a)**100 - (1-a)**100)/(a*(2**100))
mpfr('354224848179261915075.00000000000000000000000248',150)
>>> gmpy2.fib(100)
mpz(354224848179261915075L)

gmpy2也可以直接计算斐波那契数字(如上图所示)。

免责声明:我保留gmpy2