Algorithm 关于斐波那契数所需的位数

Algorithm 关于斐波那契数所需的位数,algorithm,Algorithm,我正在读S.DasGupta写的一本算法书。下面是关于第n个斐波那契数所需位数的文本片段 将添加视为 如果很小,只需一个计算机步骤 正在添加数字,32位 数字显示。但是第n个斐波那契 号码大约是 0.694n位长,随着n的增长,这可能远远超过32位。算术 对任意大数据集的操作 数字不可能被执行 在一个单一的、恒定的时间步长内 我的问题是关于例如,关于斐波那契数F1=1,F2=1,F3=2,等等。然后在上述公式中替换“n”,即0.694n代表F1约为1,F2约为2位,但对于F3等,上述公式失败。我

我正在读S.DasGupta写的一本算法书。下面是关于第n个斐波那契数所需位数的文本片段

将添加视为 如果很小,只需一个计算机步骤 正在添加数字,32位 数字显示。但是第n个斐波那契 号码大约是 0.694n位长,随着n的增长,这可能远远超过32位。算术 对任意大数据集的操作 数字不可能被执行 在一个单一的、恒定的时间步长内

我的问题是关于例如,关于斐波那契数F1=1,F2=1,F3=2,等等。然后在上述公式中替换“n”,即0.694n代表F1约为1,F2约为2位,但对于F3等,上述公式失败。我想我不太明白作者在这里的意思,有人能帮我理解一下吗


谢谢

首先,about这个词非常重要,因为在
中,第n个Fibonacci数的长度约为0.694n位
。其次,我认为作者的意思是当
n->无穷大时。尝试一些大数字并检查:)

你不能说半个字。。。位数必须四舍五入

这意味着

number of bits = Math.ceil(Math.max(0.694*n,32));
因此,n>32和n时其四舍五入

所需的位是向上舍入的base-2对数,所以这对我来说足够接近了


值0.694来自以下事实:
F(n)
是最接近(φn)的整数/√5.所以
log(F(n))
n*log(phi)-log(sqrt(5))
,而
log(phi)
是0.694。随着
n
变大,
log(sqrt(5))
和舍入迅速变得无关紧要。

我认为他只是用斐波那契数来说明他的观点,对于大数(>32位),加法不能再假设为常数,因为它涉及的不仅仅是CPU上的一条指令

为什么这个公式失败了?对于F3=2,二进制表示需要2位(3*0.694=2.082)取F50=12586269025,可以使用33位(50*0.694=35)表示,这仍然相当接近真值

N    F(N)      0.694*N
1      0         1       
2      1         1
3      1         1
4      2         2
5      3         2
6      5         3
7      8         4
8     13         4

等等,这就是我的解释。但是,这意味着您必须在超过32位之前达到f(47)=1836311903。

作者基本上描述了大数字如何影响算法的性能。过于简单的是,处理器可以非常快地添加寄存器大小的数字,如果数字超过寄存器大小,则需要执行更多的低级处理器指令。

private static int nobFib(int n)//位数Fib(n)
private static int nobFib(int n)  // number of bits Fib(n)  
{
    return n < 6 ? ++n/2 : (int)(0.69424191363061738 * n - 0.1609640474436813);
}  
{ 返回n<6±n/2:(int)(0.69424191363061738*n-0.1609640474436813); }
从0到500.000检查n,n=500.000.000,n=1.000.000.000
它基于比奈的公式。
Fibonacci序列二进制绘图需要它。

请参阅:

如果您将其四舍五入为整数,则几乎完美φ是黄金分割比,
(1+sqrt(5))/2
,或1.6180339887。看见当你解斐波那契数的递推关系时,它就与斐波那契数有关。F(n)=(φ^n-φ'^n)/√5.(φ'=1-φ)你能详细说明一下F(n)是最接近(φ^n)的整数吗/√5
并忽略公式的其余部分。@Gaurav:(φ'^n)/√5<1/2表示n>=0,我们知道结果正好是一个整数,因此可以通过舍入大的其他部分来忽略公式中的小分数部分。
private static int nobFib(int n)  // number of bits Fib(n)  
{
    return n < 6 ? ++n/2 : (int)(0.69424191363061738 * n - 0.1609640474436813);
}