最后一片落叶 发表于 2012-11-9 16:49:18

关于大数阶乘的程序实现

本帖最后由 最后一片落叶 于 2012-11-9 16:51 编辑

大数阶乘是一个有意思的话题。好像到目前为止,还没有一种方法适合任何的大数阶乘。我也是刚刚接触,觉得挺好玩。所谓的大数就是一个非常大的数,大到计算机不能直接表示,比如计算机只能表示100位的数,而我要求的最后结果可能有300位,那我必须利用只能表示100位的计算机求出300位的准确结果来。这是第一个难点。第二个是对速度的要求。速度不能太慢,算法要有效率。

阶乘估计大家都知道,就是一列数的乘积,符号用!表示。比如4的阶为:4!=4*3*2*1=24.
先写一个简单的求阶乘的程序。
#include "stdio.h"#include "stdlib.h" int main(int argc, char* argv[]){         long i,n,p;         printf("n=?");         scanf("%d",&n);         p=1;         for (i=1;i<=n;i++)                  p*=i;         printf("%d!=%d/n",n,p);         return 0;}该程序用的循环求阶乘。再来一个稍微改进一点的程序#include   <iostream.h>   
long   int   fac(int   n);   
void   main()   
{   
          int   n;   
          cout<<"input   a   positive   integer:";   
          cin>>n;   
          long   fa=fac(n);   
          cout<<n<<"!   ="<<fa<<endl;   
}   
long   int   fac(int   n)   
{   
          long   int   p;   
          if(n==0)   p=1;   
          else   
            p=n*fac(n-1);   
          return   p;   
}该程序用的递归求阶乘。上面的两个程序都可以求阶乘,但你试一下就知道,只能求12以内的阶乘。当n的值大于12以后,运算结果就不对了。因为这个时候结果的位数已经超过了int型的最大表示范围,想要继续计算,就要扩大表示范围,把int改为double。但这种方法只是一时的,因为n越来越大,最终也会超过double的表示范围。下面给出求大数阶乘的程序#include<time.h>#include<iostream>using namespace std;#include<iomanip> #define N 1000#define M 128void main(){       clock_tstart, end;       start= clock();       staticlong int r={1};        inti,j;       intk=0,l=0;       for(i=1;i<=M;i++)       {                        for(j=0;j<=l;j++)            {                                        r=r*i+k;                                    k=r/1000;                     r=r%1000;                              }            if(k!=0)            {                     l++;                     r=k;                     k=0;            }            j=l;            cout<<i<<"!="<<r;            for(;j>=0;j--)            {                     cout<<",";                     cout<<setw(3)<<setfill('0')<<r;            }            cout<<endl;       }       end= clock();       cout<<"Runtime: "<<(double)(end - start) /CLOCKS_PER_SEC<<"S"<<endl;       }
这个程序计算的是128的阶乘。这个数已经很大了。想计算其他的值,将128改成其他的数就可以了。这个程序肯定不是最优的,希望大家一起讨论。


页: [1]
查看完整版本: 关于大数阶乘的程序实现