斐波纳契的递归关系在大数字上的精度损失

时间:2015-10-27 16:00:52

标签: c# math fibonacci

我正在尝试使用Binet's formula来解决Fibonacci的 n 数字,其中 O(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));
    }       
}

以下示例的工作方式类似于前两个测试的魅力,但第三个测试失败了很多(结果为354224848179263111168354224848179261915075

我想我的公式的Math.Pow((1+sqrt5)/2,n)部分可能存在问题,但我尝试使用decimaldoublefloat和{{1}使用公式本身,结果永远不会是好的。

我的问题有解决办法,还是我接受使用BigInteger无法做到这一点?

编辑我尝试使用Math.Pow,但使用它BigInteger.Pow也需要1+sqrt5,这使我的代码最终看起来像这样因为铸件:

BigInteger

返回的所有值都是零。

1 个答案:

答案 0 :(得分:3)

使用双倍你总是有15位半的精确度。你不能指望更多,整数转换的输出只能与输入一样好。

这就是为什么即使Binets公式不是O(1)而是O(M(n))用于n位计算,使用F [n]小于2 ^ n其中M(n)是乘法的成本这也是取幂和对数成本的衡量标准。