阶乘(高精)
一.什么是阶乘
一个正整数的阶乘(factorial)是所有小于及等于该数的正整数的积,并且0的阶乘为1。自然数n的阶乘写作n!。
即5!=5 * 4 * 3 * 2 * 1。
二.“普通”的阶乘
阶乘的代码很好写,就如同下面一样;
#include<stdio.h>
#include<string.h>
typedef long long ll;
int main()
{
int n;
ll sum = 1;
scanf("%d",&n);
for(int i = 1; i <= n; i++)
{
sum *= i;
}
printf("%lld",sum);
return 0;
}
这就是一份完整的阶乘代码,但是即使用上了long long类型,阶乘也只能算到20,在往上就会超过精度了。
所以我们需要高精来解决更大阶乘数计算
三.高精度的阶乘
#include<stdio.h>
#include<string.h>
#define N 2000100
typedef long long ll;
int a[N];
//数组a用来存储阶乘后值的每一位
int k = 1;
//k代表阶乘后的值的位数
void cheng(int x)
{
int ch = 0;
//利用一个ch用来存储进位
for(int i = 1; i <= k; i++)
{//循环做乘法
//这里也可以从2开始,因为乘1结果都是一样的
a[i] = a[i] * x +ch;
//每一位都要乘x,同时加上进位
ch = a[i] / 10;
a[i] = a[i] % 10;
//这里a[i]留下个位数的数值
//剩下的进位
}
while(ch > 0)
{//假如还有进位没完成,就需要位数自加
//然后存储上进位的值
a[k+1] = ch % 10;
ch /= 10;
k++;
}
}
int main()
{
int n;
scanf("%d",&n);
a[1] = 1;
//数组第一位一定要赋值为1,不然任何数乘0都是0
for(int i = 1; i <= n; i++)
cheng(i);
for(int i = k; i >= 1; i--)
{//逆序输出
printf("%d",a[i]);
}
return 0;
}
在这个高精代码里面注意的就只有三个地方:
①
int ch = 0;
for(int i = 1; i <= k; i++)
{
a[i] = a[i] * x +ch;
ch = a[i] / 10;
a[i] = a[i] % 10;
}
一定要利用一个ch来记录进位,因为在乘法过程中,一定是原来位数上的数乘x再加上进位的数
②
while(ch > 0)
{
a[k+1] = ch % 10;
ch /= 10;
k++;
}
一定要判断一下进位是否完成
③
for(int i = k; i >= 1; i--)
{
printf("%d",a[i]);
}
因为前面的操作个位数在首位元素,所以在满足数输出首位元素应该是最高位的习惯下,要逆序输出