由于大数阶乘的位数超出了int的表示范围,我们只能用一个数组来放置它,那么首先确定结果数组的大小,这个可以根据阶乘位数的计算公式来计算,这里有个关键点,在定义数组的时候可以先给出一个指针,在原则上指针和数组是一致的,等确定了大小后就可以利用malloc()来申请一块内存来,这个内存就是我们最后的结果数组,如果直接定义数组就会遇到必须确定数组大小的麻烦,得到了数组后然后我们对初始化,注意必须个位赋值为一,这时候我们进入了关键的迭代,进入了for()大循环,在这里结果数组就是一个寄存器,每循环一次,我们都把结果放在a[j]里面,此时a[j]里面很可能已经出现大于9的数字,这就需要向a[j+1]进位,此时我们设计一个子函数来实现这个功能,dgCal()函数,设置了一个进位标志位cy, 传入此函数的是一个结果数组,和最高位非零的下标,首先遍历整个数组的非零部分,从个位开始,进位标志位赋初值为0,进入循环后,首先判读进位标志位是否需要进位,如果有值,肯定是从下面传上来的,加到自己的数字上面,然后开始判断自己的数字是属于下面三种那种情况,根据情况判断如何设置进位位。遍历完后,进入主函数进行下一轮的循环与(i+1)相乘。
这个算法的亮点就是结果数组的定义和,进位子函数的设计很好。
#include “math.h”
#include “stdio.h”
#include “stdlib.h”
void jinwei(int a[],int pos)
{
int i,cy=0; //进位值 ,cy装载循环一次数组中需要进位的值
for(i=0;i<=pos;i++)//从0-pos逐个检查是否要进位
{
a[i]+=cy;
if(a[i]<=9)//不需进位
{
cy=0;//进位制为0
}
else if(a[i]>9&&i{
cy=a[i]/10;//进位值
a[i]=a[i]%10;
}
else if(a[i]>9&&i>=pos)//需进位,已达到最高位
{
while(a[i]>9)//循环向前进位
{
cy=a[i]/10;
a[i]=a[i]%10;
i++;
a[i]=cy;
}
}
}
}
int main( )
{
int i,j;
int *a;//结果数组
int num=200;//要求的阶乘数
int pos=0;//最高位下标
int digit=0;//阶乘的位数
double sum=0;
for(i=1;i<=num;i++)
{
sum += log10((double)i);//计算阶乘的位数
}
digit=(int)sum+1;//阶乘的位数
if(!(a=(int *)malloc( (digit+1) * sizeof(int) )))//分配内存
{
printf(“内存分配失败!\n”);
return 0;
}
for(i=0;i<=digit;i++)
{
a[i]=0;//初始化
}
a[0]=1;//个位为1
for(i=2;i<=num;i++)//2-num逐个与原来的结果相乘
{
for(j=digit;j>=0;j–)//查找最高位的下标
{
if(a[j]!=0)
{
pos=j;
break;
}
}
for(j=0;j<=pos;j++)
{
a[j]*=i;//逐个相乘
}
jinwei(a,pos);//乘完一轮后进位处理
}
for(j=digit;j>=0;j–)//查找最高位的下标
{
if(a[j]!=0)
{
pos=j;
break;
}
}
printf(“200的阶乘:\n”);
printf(“位数:%d\n”,pos+1);
for(i=pos;i>=0;i–)
{
printf(“%d”,a[i]);//打印结果
}
printf(“\n”);
return 0;
}