阶乘计算升级版(12位以上的阶乘)

2019-04-14 19:27发布

本题要求实现一个打印非负整数阶乘的函数。 其中N是用户传入的参数,其值不超过1000。如果N是非负整数,则该函数必须在一行中打印出N!的值,否则打印“Invalid input”。
基本思路:
我们知道,当n的值增大时,阶乘的结果会急剧增大,当n大到一定数后即使是unsigned long类型也无法保存结果,这时只能采取别的方法来保存结果.
这里主要采用模拟手算的方法,步骤如下:
  1. 开辟一个足够大的整形数组用于存储计算的结果;
  2. 对于数组的每一位模拟手算的过程:把每一位相乘的结果的个位留下作为本位,高位作为进位加到下一位的计算中去
  3. 对于最高位的进位,同样留下个位作为进位值,进位的高位除以10再将个位作为更高位的值,直到进位位0为止.
  4. 为方便计算将结果逆序存储在数组上

以下为手算的实例以帮助理解

这里写图片描述 #include void fac(const int n); int main() { int n; scanf("%d",&n); fac(n); return 0; } void fac(const int n) { int i,j; long result=1; if(n>=0&&n<=12) //可直接计算 { for(i=1;i<=n;i++) { result*=i; } printf("%d!=%d ",n,result); } else if(n>=12&&n<=1000) //模拟手算过程 { int data[3000]; //存储每一位的结果 int carry=0; //存储进位 int temp; //存储每一位相乘后的结果 int digit=1; //存储当前位数 data[0] = 1; //初始化第一位数据 /*一位一位的相乘,每一位模拟手算的过程*/ for(i=1;i<=n;i++) { /*遍历数组的每一位和i相乘*/ for(j=0;j10; //相乘的结果个位留在本位,高位作为进位加到下一位中去 carry = temp/10; } /*最高位有进位的处理:进位可能很大,数组每一位保留进位的个位后进位除以10,依次循环*/ while(carry!=0) { data[digit] = carry%10; //存储进位的个位 digit++; //当前位数+1存储进位的下一位 carry=carry/10; //进位除以10,为下一次循环做准备 } } /*反向输出数组内容*/ printf("%d!=",n); for(i=digit-1;i>=0;i--) { printf("%d",data[i]); } printf(" "); } else { printf("Invalid input "); } } 因本人水平有限,难免会有错误的地方,望各路大神多多指教,本人QQ1481263718欢迎来交流