Python的防止溢出的错误,同时处理大量的浮点数字和整数(Python prevent overf

2019-10-20 02:34发布

我工作的一个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。

Answer 1:

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



Answer 2:

我不知道这是可以接受的给你,但你可以只使用整数运算计算作为使用递推关系的FIB数量(例如,F3 = F2 + F1)。

因为Python 2.5?,你可以做任意精度的整数运算 - 几乎消除溢出的问题 - 如果你试图计算F(10000)它无疑会变得非常慢。

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

添加

你可以很容易忽视的是,小数类包括平方根法。 您将需要改用math.sqrt()这个方法,因为你将需要保留小数点类的全精度。

也SQRT(5)是一种相对昂贵的操作。 只计算它一次



Answer 3:

一个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。



Answer 4:

你的我怎么能改善这个代码语句...是一种模糊的,所以我会把它意味着缩短您的代码:

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