大菲波那契数的计算程序

 
大菲波那契数的计算程序
对于较大的n,由于f[n]已超过计算机字长所能表示的范围,如何利用计算机来精确地生成的f[n]值呢?例如,当n=100时,f[1000]的值大大超过了无符号长整数所能表示的范围,很多对程序设计已有相当多经验的程序员对此不知所措。
事实上这一问题的解决非常简单,设想让我们用纸和笔来计算f[100],所要做的无非是反复进行多位数的加法,如果我们将每位数用数组的一个单元来表示,一个菲波那契数用一个数组表示,只要设计一个多位数的加法程序,相应地,将前面计算小菲波那契数的程序加以改造,问题不就解决了吗?!
为此,定义一个多位数的结构:
#define RADIX                   10
 
typedef struct tagMPInt
{
    int      length;
    int bit[MAXBITS];
}    MPInt;
实现多位数加法的函数为:
void MPIntAdd(MPInt *z, MPInt *x, MPInt *y)
{
    int     i, carry;
    long t;
 
    i = 0;
    carry = 0;
    while (i < x->length && i < y->length)
         {
                   t = (long)x->bit[i] + y->bit[i] + carry;
                   z->bit[i] = (int)(t % RADIX);
                   carry = (int)(t / RADIX);
                   i++;
         }
 
    if (x->length > y->length)
                   while (i < x->length)
                   {
                            t = (long)x->bit[i] + carry;
                            z->bit[i] = (int)(t % RADIX);
                            carry = (int)(t / RADIX);
                            i++;
                   }
 
    if (x->length < y->length)
                   while (i < y->length)
                   {
                            t = (long)y->bit[i] + carry;
                            z->bit[i] = (int)(t % RADIX);
                            carry = (int)(t / RADIX);
                            i++;
                   }
 
    if (carry != 0)
         {
                   z->bit[i] = carry;
                   i++;
         }
 
    z->length = i;
}
 
大菲波那契数的计算程序为:
// File: FibBig.C
 
#include "MPArth.h"
 
void FibTable()
{
    MPInt        F0, F1;
    MPInt        f0, f1, f;
    int               i, n;
    FILE          *fp = fopen("fib.dat", "w");
 
    n = 250;
    MPIntSetValue1(&F0, 1);                   // Set fib[0]
    fprintf(fp, "fib[ 0]=1/n");
    MPIntSetValue1(&F1, 1);                   // Set fib[1]
    fprintf(fp, "fib[ 1]=1/n");
    f0 = &F0;
    f1 = &F1;
    for (i = 2; i <= n; i++)
         {
                   MPIntAdd(f0, f0, f1);
                   // Swap f0, f1
                   f = f0;
                   f0 = f1;
                   f1 = f;
                   fprintf(fp, "fib[%3d]=", i);
                   MPIntPrint(f1);
         }
         fclose(fp);
}
 
程序MPAdd有很大的改进余地,该程序的设计完全模拟手工演算过程,用一个字长存放一个十进制位,没有充分利用计算机的空间资源和计算能力。容易看出,若将基数RADIX加大,可以加快问题求解的速度。例如,将RADIX的宏定义改为
#define RADIX                   10000
不必修改程序,计算速度将加快4倍。当然,RADIX=256时,可以充分地发挥计算机的时空效能,这时已不需要1000位来存放一个菲波那契数,但必须将相应的结果转换为十进制,以符合自然数的书写习惯。
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值