斐波那契's递归关系在大数上的精度损失

本文关键字:损失 精度 关系 递归 | 更新日期: 2023-09-27 18:19:24

我正在尝试使用Binet的公式来解决斐波那契的n数字与 0 (1)时间复杂度。

class Application
{
    static void Main(string[] c)
    {
        Console.WriteLine($"Fib(15) : Expected 610 got : {Fibonacci(15)}");
        Console.WriteLine($"Fib(20) : Expected 6765 got : {Fibonacci(20)}");
        Console.WriteLine($"Fib(100) : Expected 354224848179261915075 got : {Fibonacci(100)}");
        Console.ReadKey();
    }
    private static BigInteger Fibonacci(int n)
    {
        double sqrt5 = Math.Sqrt(5d);
        return new BigInteger((1/sqrt5)*Math.Pow((1 + sqrt5)/2, n) - (1/sqrt5)*Math.Pow((1 - sqrt5)/2, n));
    }       
}

下面的例子在前两个测试中非常成功,但在第三个测试中却失败了很多(结果是354224848179263111168 vs. 354224848179261915075

我猜这可能是我的公式的Math.Pow((1+sqrt5)/2,n)部分的问题,但我尝试使用公式使用decimal, double, floatBigInteger本身,结果从来都不是好的一个。

是否有办法解决我的问题,或者我应该接受我不能使用Math.Pow做到这一点?

编辑我尝试使用BigInteger.Pow,但要使用它1+sqrt5也需要是BigInteger,这使得我的代码看起来像这样在结束时,因为cast:

double sqrt5 = Math.Sqrt(5d);
return new BigInteger(1/sqrt5)*BigInteger.Pow(new BigInteger(1 + sqrt5/2), n) - new BigInteger(1 / sqrt5) * BigInteger.Pow(new BigInteger((1 - sqrt5)/2), n);

斐波那契's递归关系在大数上的精度损失

使用double总是有15位半的精度。你不能期望更多,整数转换的输出只能和输入一样好。

这就是为什么对于n位计算,即使是binet公式也不是O(1)而是O(M(n)),使用F[n]小于2^n,其中M(n)是乘法的代价,这也是指数和对数的代价的度量。