第8章课后第18题要求“编程计算并输出1~40之间所有数的阶乘”。40的阶乘远远超过了长整型所能表示的范围,因此该题目涉及到大整数的存储和大整数乘法运算问题(也称作高精度运算)。大整数存储的解决方案就是把大整数存储到一个数组中,每个数组元素存储该数的一位(也可以是多位数字)。在阶乘这个问题中,阶乘的值逐渐增大,变成一个大整数,因此我们把阶乘的值存储到一个数组中。比如8的阶乘等于40320,在数组中的存储如下图所示:
数组的第0位存储数的个位,第1位存储数的十位,……。那么如何计算9的阶乘呢?按照整数的原始定义,40320 = 4*10000 + 0*1000 + 3*100 + 2*10 + 0*1, 则9!= 40320*9 = 4*9*10000+ 0*9*1000 + 3*9*100 + 2*9*10 + 0*9*1,除了个位和千位,其它3个位都大于10 (十位:18,百位:27,万位:36),比如十位是18个10,实际上是1个百加8个10,1个百应该加到百位上去,因此,向百位进位1,十位只留8。百位是27个百,加上进位1是28个百,即2个千加8个百,向千位进位2,百位留8。千位等于0加上进位2,还是2,没有给万位进位。万位等于36个万,即3个10万加6个万,向高位进位3,万位留6。数据增多1位。9!= 362880,在数组中的存储如下图所示:
把上述计算过程转化为程序时,用一个循环语句从个位开始执行如下几步操作:
1.和下一个数(上例中是9)相乘;
2.乘积和进位相加;
3.第2步的和除以10得到给高位的进位,余数保留在该位。
具体程序如下:
#include "stdio.h"
int main()
{
int num_array[50]={0,2,3,0,4}; //存储一个大整数
int size=5; //数的位数
int next_num;
int i;
int c=0; //进位
printf("Please input next number:") ; //输入的乘数不能太大,否则溢出。
scanf("%d",&next_num);
for(i=0;i
=0; i--)
printf("%d ",num_array[i]);
}
在上面程序的基础上,再加一重循环(next_num从2到40),num_array数组中的数从1开始,就可以计算1~40间所有数的阶乘了。请大家自己去完成该程序。