想要学会大数阶乘,那么首先要学会基础的大数加法
以前我们写加法:
#include<stdio.h>
int main()
{
int a,b;
scanf("%d %d",&a,&b);
printf("%d",a+b);
return 0;
}
对于比较小的数字可能还可以计算,但是对于超出整形范围(-2147483648~2147483647())的数字,可能就没有办法了。
对于给定的整数a,b,计算a+b其中a,b的位数N>=10000,记住是位数,不是值,
代码如下:
#include<stdio.h>
#include<string.h>
#define MAXLEN 10000
int main()
{
int i, up, tmp;
char buffer[MAXLEN+1]={0},a[MAXLEN+1]={0},b[MAXLEN+1]={0};
//逆序输入a
scanf("%s",buffer);
for(tmp=0,i=strlen(buffer)-1;i>=0;i--)
a[tmp++]=buffer[i]-'0'; // 转换成对应ASCII码里面,就是对应的十进制的数字
//逆序输入b
scanf("%s",buffer);
for(tmp=0,i=strlen(buffer)-1;i>=0;i--)
b[tmp++]=buffer[i]-'0'; // 转换成对应ASCII码里面,就是对应的十进制的数字
if(a[0]==0&&b[0]==0) // 这是加数都为零的情况
{
printf("0");
return 0;
}
//计算
for(up = 0,i = 0; i<MAXLEN ;i++)
{
tmp = a[i] + b[i] + up; // 暂时存储数值
a[i] = tmp%10;
up = tmp/10; // 进位
}
// 输出结果
for(i = MAXLEN;i>=0;i--)
if(a[i]!=0)
for(i;i>=0;i--)
printf("%d",a[i]);
return 0;
}
接下来就是大数阶乘
7-8 计算n!(n要能大于13) (300 分)
编写程序,求n!(n的值要能大于13),其结果用一个不超过64位的十进制数输出。
输入格式:
输入一个非负整数,其值介于2到49之间的数。
输出格式:
对每一个输入的整数,在一行中输出相应的阶乘值,输出结果的高位用0填充。
输入样例1:
在这里给出一组输入。例如:
7
输出样例1:
在这里给出相应的输出。例如:
5040
输入样例2:
在这里给出一组输入。例如:
49
输出样例2:
在这里给出相应的输出。例如:
608281864034267560872252163321295376887552831379210240000000000
代码如下:相比大数加法更为简洁
#include<stdio.h>
#include<string.h>
#define MAXLEN 10000
int main()
{
int n, i, j, up, tmp;
char arr[MAXLEN+1] = {1};
// 输入n
scanf("%d",&n);
//计算
for(i = 2;i <= n;i++)
{
for(up = 0,j = 0;j <= MAXLEN;j++)
{
tmp = arr[j] * i + up;
arr[j] = tmp % 10;
up = tmp / 10;
}
}
// 输出结果
for(i = MAXLEN;i>=0;i--)
if(arr[i]!=0)
for(i;i>=0;i--)
printf("%d",arr[i]);
return 0;
}
还有就是在网上看到别人的办法
#include <stdio.h>
void Print_Factorial ( const int N );
int main()
{
int N;
scanf("%d", &N);
Print_Factorial(N);
return 0;
}
void Print_Factorial ( const int N )
{
int num[3001]={0};//用于记录每一位
int ans=1;
int tmp=0; //用于记录每一位和i相乘的临时结果
int k=0; //用于记录当前最大的下标
int carry=0; //来自低位别的进位
if(N<0)
printf("Invalid input\n");
else if(N==0)
printf("1\n");
else if(N>0&&N<12)
{
for(int i=1;i<=N;i++)
ans=ans*i;
printf("%d\n",ans);
}
else{
num[0]=1;
for(int i=2;i<=N;i++)
{
for(int j=0;j<=k;j++)
{
tmp=num[j]*i+carry;
num[j]=tmp%10;
carry=tmp/10;
}
//tmp=tmp/10;
while(carry) //本轮乘完最高位还有进位
{
num[++k]=carry%10;
carry=carry/10;
//k++;
}
}
for(int i=k;i>=0;i--)
printf("%d",num[i]);
printf("\n");
}
}
以上两种方法可以自行选择,我觉得第一种方法更为好一点