对于大数求阶乘

/*
*  作用 : 计算int最大值/10以内数的阶乘(约在2147483647 / 10内)
*         必要时需修改MAX_DIGITS位数及result数组为long
*
*  作者 : 冯美银
*  时间 : 2008-09-13
*
*  思想 : 把int数组每一个元素当一位数,进行计算,因此就可以表示任意大的数值
*         第0个元素,存储结果的位数,从第1元素开始分别表示个位,十位.....
*/

#include <stdio.h>
#include <assert.h>

const int MAX_DIGITS = 1000000; //设置结果最大的位数
int result[MAX_DIGITS];   //保存一个数的阶乘的结果
        //初始化工作在函数内还要进行,以免传入未初始化的局部变量
/*
*  如果结果数组有大于10的元素,返回false
*/
bool TestResIsCurrent(int * presult);

/*
*  作用 : 计算int最大值/10以内数的阶乘
*  参数 : resultArray 一个int数组,用于保存阶乘结果
*         num 为一个小于int最大值/10的以内的数(约在2147483647 / 10内)
*             (因为大于这个数与每一元素相乘可能会溢出)
*  返回 : 指针结果数组的指针
*/
int * BigNumFact(int * resultArray,int num)
{
 resultArray[0]=1;     //第0个保存结果的位数
 int &digits = resultArray[0];  //定义一个别名,以便程序阅读
 resultArray[1] = 1;     //初始化结果值为1
 
 int i;        //初始化数组其它为0
 for (i = 2; i < MAX_DIGITS; i++) resultArray[i] = 0;
 
 for (i = 2; i < num+1; i++)        //把保存在resultArray中的数,使用循环依次乘2到num
 {
  if (digits == 0) break;        //当digits为0,表示结果位数大于数组容量,退出
  
  int k;
  for (k=1; k < digits+1; k++) resultArray[k] *= i;
  
  for (k=1; k < digits+1; k++)      //从第一位开始向最高位处理每一个大于10的位数
  {   
   if (resultArray[digits] > 10) digits++;   //如果最高位大于10,则结果增加一位
   if (digits > MAX_DIGITS-1)      //如果结果大于最大结果位数,则退出,不用再进行计算
   {
    digits = 0;
    break;
   }

   if (resultArray[k] > 10)      //如果该为大于10
   {
    resultArray[k+1] += resultArray[k] / 10; //则前一位等于原值+当前位除10
    resultArray[k] %= 10;      //当前位为除10的余数
   }
  }
 }
 assert(TestResIsCurrent(resultArray));
 return resultArray;
}

/*
*  从高向低位打印结果值
*/
void PrintRes( int * presult)
{
 int &digits = presult[0];
 if (digits == 0)
  printf("/tThe array is not enough digits to store the result!/n");
 else
 {
  printf("/tThe result digits is : %d /n/t",presult[0]);

  for (int x = digits; x > 0; x--)
   printf("%d",presult[x]);

  puts("");
 }
}

bool TestResIsCurrent(int * presult)
{
 int &digits = presult[0];
 for (int x = 1; x < digits+1; x++)  //如果都没大于10,最后x还要++,因此条件只能是大于digits
 {
  if (presult[x] > 10)
   break;
 }
 return (x > digits);
}

void main()
{
 //printf("%d",sizeof(int)); //4

 /*
 for (int x=2; x < 1000; x++)
 {
  printf(" %d! result : /n",x);
  PrintRes(BigNumFact(result,x));
 }
 */

 int x=147483647;  //需很长时间
 printf(" %d! result : /n",x);
 PrintRes(BigNumFact(result,x)); 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值