一个C语言实现的高精度求大数阶乘的高效算法[转]

/*
 * 修改后的C源程序
 * 4.剖析和优化下面计算阶乘的C程序,要求写出报告,必须有分析测量数据作为支持,同时应该用到课堂上所讲的方法和工具。
 *
 * 用数组的方法解决大数、巨数的阶乘结果越界的问题。具体算法中有最朴实的乘法运算思想。  
 * */

/*Header 包含头文件*/
#include <stdio.h>
#include <stdlib.h> /* 哪个函数用到这个库? */

#define M 1000000000L /*定义*/
#define N 60000  /* 定义数组大小:确保保存最终运算结果的数组足够大*/

/* Funtion函数声明*/
int multiply(int n, unsigned int prod[N], int highest);
void print(unsigned int prod[N], int highest);

/* 主程序 */
int main(int argc, char * argv[]) {
 int i, n = 0, highest = 0; /* 整数n是阶乘大小。highest是位数(可是为什么不初始化为1?highest应该小于N) */
 int prod[N] = {1, 0};  /* 将结果先初始化为1。也就是说,键盘没输入参数是默认输入参数为0,结果为1*/

 if (argc > 1) n = atoi(argv[1]);  /* 命令行参数:从键盘接收阶乘大小n。*/

 for (i = 2; i <= n; i++)   /* 开始阶乘,阶乘元素从2开始依次“登场” */
  highest = multiply(i, prod, highest); /* 调用阶乘子程序 */

 print(prod, highest);

 return 0;
}

/*
 *计算阶乘的子程序
 *
 * */
int multiply(int n,    /* n:要求阶乘的数 */
      unsigned int prod[N],  /* 保存最终运算结果的数组 */
      int highest)   /* 阶乘结果的位数 */
{
 /* tmp是阶乘的任一元素与临时结果的某位的乘积结果 */
 unsigned long long tmp;    /* if your compiler supports C99 */
 /*unsigned __int64 tmp; */   /* if you use Visual C or Borland C */
 int carrier = 0;  /* 进位 */
 int i;

 /* 按最基本的乘法运算思想来考虑,将临时结果的每位与阶乘元素相乘 */
 for (i = 0; i <= highest; i++) {
  /* 相应阶乘中的一项与当前所得临时结果的某位相乘(加上进位) */
  tmp = n;
     tmp *= prod[i];
  tmp += carrier;
  /* 上面3式等价于 tmp = prod[j-1] * i + carrier; j表示此处的临时累加器i,而i表示外层累加器i */

  prod[i] = tmp % M; /* 更新临时结果的位上信息 */
  carrier = tmp / M; /* 看是否有进位 */
 }

 if (carrier)   /* 如果有进位 */
  prod[++highest] = carrier; /* 新加一位,添加信息。位数增1 */
  carrier /= 10; /*看还能不能进位 */
 
 return highest;
}

/*
 * 输出显示结果
 *
 * */
void print(unsigned int prod[N], int highest) {
 printf("%u", prod[highest]); /* ISO C99标准支持 *//* 显示结果 */
 while (highest > 0)
  printf("%09u", prod[--highest]);

 return;
}

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值