我正在尝试使用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));
}
}
以下示例的工作方式类似于前两个测试的魅力,但第三个测试失败了很多(结果为354224848179263111168
与354224848179261915075
。
我想我的公式的Math.Pow((1+sqrt5)/2,n)
部分可能存在问题,但我尝试使用decimal
,double
,float
和{{1}使用公式本身,结果永远不会是好的。
我的问题有解决办法,还是我接受使用BigInteger
无法做到这一点?
编辑我尝试使用Math.Pow
,但使用它BigInteger.Pow
也需要1+sqrt5
,这使我的代码最终看起来像这样因为铸件:
BigInteger
返回的所有值都是零。
答案 0 :(得分:3)
使用双倍你总是有15位半的精确度。你不能指望更多,整数转换的输出只能与输入一样好。
这就是为什么即使Binets公式不是O(1)而是O(M(n))用于n位计算,使用F [n]小于2 ^ n其中M(n)是乘法的成本这也是取幂和对数成本的衡量标准。