为什么我的小蟒蛇斐波那契探测器失败了?

时间:2016-12-31 08:20:39

标签: python algorithm fibonacci

由于某种原因,我必须确定一个大数字是否是斐波纳契数,所以我从互联网上复制了一些代码并对其进行了一些修改,当它的大输入时似乎运行不好。这是代码:

# python program to check if x is a perfect square

import math

# A utility function that returns true if x is perfect square
def isPerfectSquare(x):
    s = int(math.sqrt(x))
    boo = (s*s == x);
    return boo

# Returns true if n is a Fibinacci Number, else false
def isFibonacci(n):

    # n is Fibinacci if one of 5*n*n + 4 or 5*n*n - 4 or both
    # is a perferct square
    b = 5*n*n+4;
    c = 5*n*n-4;
    return isPerfectSquare(b) or isPerfectSquare(c)

# A utility function to test above functions

a = int(input("give me the number"));
print(isFibonacci(a))

当我输入610时,它会按计划输出true,但是当我输入

"215414832505658809004682396169711233230800418578767753330908886771798637" 

我知道的是我制作的另一个java程序中的第343个斐波纳契数。它输出错误令人惊讶。那是因为数字太大所以会犯错误吗?但我认为python应该能够处理巨大的数字,因为它基于你拥有的内存?是我的程序中的问题还是因为它的输入太大? THX!

4 个答案:

答案 0 :(得分:5)

你精确度下降了。对于n > 1e45(大约),(n**0.5)**2 != n。尝试使用模块gmpy2.isqrt()中的gmpy2.square()gmpy2 - 它们可以处理非常大的整数。

答案 1 :(得分:1)

我用Matlab中的mupad生成的Fibonacci数字检查了它(使用numlib :: fibonacci(n))。这是因为精确。 Python无法检测超过52的精度,因此对于大于2 ^ 52的数字,精度将会丢失。您可以使用第76个斐波纳契数和第77个斐波纳契数来检查它以查看问题。 第76届斐波那契数字:3416454622906707 第77届斐波那契数字:5527939700884757

答案 2 :(得分:1)

正如已经指出的那样,问题仅来自math.sqrt,这是一个浮点操作,意味着不完全精确(与整数运算不同)。 python中浮点数的精度约为16,这意味着对超过16位总是的数字的精度浮点运算变坏。

您可以使用标准库中包含的math.sqrt模块中的Decimal类型,而不是使用浮点数(decimal将您的整数隐式转换为浮点数)。这是一种具有可变,可控精度的浮点类型。要修复您的程序,只需将isPerfectSquare函数替换为:

import decimal
def isPerfectSquare(x):
    # Set decimal precision and convert x to Decimal type
    decimal.getcontext().prec = len(str(x))
    x = decimal.Decimal(x)
    # Check if perfect square
    s = int(x.sqrt())
    boo = (s*s == x);
    return boo

此处精度设置为等于输入数字的位数,由输入数字的str表示的长度给出。

答案 3 :(得分:0)

与52位数之后的python松散精度(在点之前和之后的总数)有关。您必须使用从模块gmpy2.square()导入的gmpy2这是您处理大数字的唯一方法。