我工作的一个Python程序在斐波那契序列来计算数字 。 这里是我的代码:
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号:
这可以计算出许多在Fibonacci序列中的数字,但我得到溢出错误。
我怎样才能提高此代码,防止溢出的错误?
注:我使用Python 2.7。
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')
其他库mpmath和gmpy2 。
>>> 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
。
我不知道这是可以接受的给你,但你可以只使用整数运算计算作为使用递推关系的FIB数量(例如,F3 = F2 + F1)。
因为Python 2.5?,你可以做任意精度的整数运算 - 几乎消除溢出的问题 - 如果你试图计算F(10000)它无疑会变得非常慢。
此外,检查出小数模块 - IIRC正确的,你可以使用与Python 2.7,你可以指定小数运算的精度 - 这将允许你继续使用相同的算法 - 除了使用十进制类型。
添加
你可以很容易忽视的是,小数类包括平方根法。 您将需要改用math.sqrt()这个方法,因为你将需要保留小数点类的全精度。
也SQRT(5)是一种相对昂贵的操作。 只计算它一次
一个Python双具有有限的值。 然而一个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。
你的我怎么能改善这个代码语句...是一种模糊的,所以我会把它意味着缩短您的代码:
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!'
高于一切第二个将第一循环,确保没有错误,如果没有,它会继续打印。
文章来源: Python prevent overflow errors while handling large floating point numbers and integers