我正在尝试打印Fibonacci序列,并且在大约第600个术语后它总是返回溢出错误。
def fib():
import math
from math import sqrt
print "\nFibonacci Sequence up to the term of what?"
n=raw_input(prompt)
if n.isdigit():
if int(n)==0:
return 0
elif int(n)==1:
return 1
else:
n_count=2
print "\n0\n1"
while n_count<int(n):
fib=int(((1+sqrt(5))**n_count-(1-sqrt(5))**n_count)/(2**n_count*sqrt(5)))
print fib
n_count+=1
fib()
else:
print "\nPlease enter a number."
fib()
fib()
当我运行时:
Traceback (most recent call last):
File "<pyshell#21>", line 1, in <module>
fib()
File "<pyshell#20>", line 15, in fib
fib=int(((1+sqrt(5))**n_count-(1-sqrt(5))**n_count)/(2**n_count*sqrt(5)))
OverflowError: (34, 'Result too large')
答案 0 :(得分:3)
嗯,首先,让我们把那个大表达分成小的表达式,这样我们就可以看出它出了什么问题。并使用调试器或一些print
语句来查看哪些值导致出错。这样,我们不只是在黑暗中刺伤。
如果您这样做,可以告诉(1+sqrt(5)**n_count)
n_count
点击605
时>>> (1+sqrt(5))**604
1.1237044275099689e+308
>>> (1+sqrt(5))**605
OverflowError: (34, 'Result too large')
引发此异常。你可以很容易地验证:
>>> 1e308
1e308
>>> 1e309
inf
那么,为什么这是一个问题?
嗯,Python float
值与其整数不同,不是任意大小的,它们只能保存IEEE double可以容纳的值:*
import decimal
s5 = decimal.Decimal(5).sqrt()
所以,问题是你方程中的一个项大于最大可能的IEEE双。
这意味着你需要选择不同的算法,**或者获得一个“大浮动”库。
碰巧,Python在decimal
模块中有一个内置的big-float库。当然顾名思义,它处理十进制浮点数,而不是二进制浮点数,因此如果你使用它会得到不同的舍入错误。但是考虑到你的代码,你可能并不关心舍入错误。
所以:
fib=int(((1+s5)**n_count-(1-s5)**n_count)/(2**n_count*s5))
......然后......
float
*事实上,限制是特定于平台的;实现不是必需使用IEEE {1}}的双精度数。因此,使用sys.float_info
查看平台的最大值。但它几乎总是1.7976931348623157e+308
。
**请注意,您使用的算法与天真算法相比的唯一优势是它允许您直接逼近第N个斐波纳契数,而无需计算前面的N-1。但是既然你想要将它们打印出来,那么你就没有任何优势。你只是得到了缺点 - 这是一个近似值;它更复杂;它需要浮点数学,这可能会出现舍入误差;它比较慢;它需要更多的记忆;在大多数平台上,大多数语言中的内置浮点类型都不能容纳F(605),......所有这些都没有任何好处似乎不值得。
答案 1 :(得分:1)
正如abarnert指出的那样,浮游物在蟒蛇中是有限的。您可以通过
查看限制>>> import sys
>>> sys.float_info
sys.float_info(max=1.7976931348623157e+308, max_exp=1024, max_10_exp=308, min=2.2250738585072014e-308, min_exp=-1021, min_10_exp=-307, dig=15, mant_dig=53, epsilon=2.220446049250313e-16, radix=2, rounds=1)
如果你在加注之前除以2,你会得到更多的术语:
int(( ((1+sqrt(5))/2)**n_count - ((1-sqrt(5))/2)**n_count)/sqrt(5))
但是,由于斐波纳契序列呈指数增长,你很快就会碰到同一堵墙。尝试通过保留最后两个术语并添加它们来计算Fibonacci。这样你就可以使用整数。