首页 > 代码库 > 大数相加相乘及阶乘

大数相加相乘及阶乘

    大数的相加相乘和阶乘操作都可能会导致结果的溢出,可以把它们转换成字符串,再进行运算,这里需要注意的是,习惯上的加法乘法运算都是从低位开始运算的,先计算个位,个位向高位进位,依次进行直到最高位。字符串表示一个数字的时候如”3476”,它的低位数字在最大下标处,为了与习惯上的操作保持一致,可以先把字符串反转,求出结果之后再把结果反转回来即可。接下来的加法操作就使用了反转的方法,乘法操作也可以使用类似的反转,但本文的乘法操作没有使用反转。计算出的结果可以保存在字符串中,也可以保存在整型的数组中,接下来的加法操作就把结果保存在字符串中,而乘法和阶乘的操作则把结果保存在整型数组中。在求阶乘操作的时候,每个数字位存放在一个整型变量中,外面使用一层循环,让每个数位都乘以2,3,4,5,6…,并处理进位,这样就可以把数的阶乘求出来了。

# include <iostream>
# include <cstdlib>
# include <string>
# include <cstring>
# include <algorithm>
# include <cassert>
using namespace std;
const int N=110;

void numadd(int a,int b)  //相加
{   
	assert(a>0&&b>0);
	char *t1=new char [100];
	char *t2=new char [100];
	sprintf(t1,"%d",a);
	sprintf(t2,"%d",b);
	string oper1(t1);
	string oper2(t2);  
	reverse(oper1.begin(),oper1.end()); //反转字符串
	reverse(oper2.begin(),oper2.end());
	int i=0,j=0;
	int carry=0;  //进位
	string res(50,'0');
	int k=0;
	while(k<oper1.size()&&k<oper2.size())
	{
		res[k]=oper1[k]+oper2[k]+carry-'0';
		carry=(res[k]-'0')/10;
		if(res[k]-'9'>0)
			res[k]-=10;
		++k;
	}
	while(k<oper1.size())
	{
		res[k]=oper1[k]+carry;
		carry=(res[k]-'0')/10;
		if(res[k]-'9'>0)
			res[k]-=10;
		++k;
	}
	while(k<oper2.size())
	{
		res[k]=oper2[k]+carry;
		carry=(res[k]-'0')/10;
		if(res[k]-'9'>0)
			res[k]-=10;
		++k;
	}
	if(carry)
	{
		res[k++]='1';
	}
	for(i=res.size()-1;i>=0;--i)
		if(res[i]!='0')
			break;
	res=res.substr(0,i+1);
	reverse(res.begin(),res.end()); //把结果反转
	cout<<res<<endl;
}

void nummulti(char a[],char b[])  //相乘
{
	if(a==NULL||b==NULL)
		return ;
	int lena=strlen(a);
	int lenb=strlen(b);
	if(lena==0||lenb==0)
		return ;
	int len=lena+lenb;
	int c[N]={0};
	int i,j;
	int flag=0;
	for(i=lena-1;i>=0;i--)
		for(j=lenb-1;j>=0;j--)
		{
			c[i+j+1]+=(a[i]-'0')*(b[j]-'0');
			if(c[i+j+1]>=10)
			{
				c[i+j]+=c[i+j+1]/10;
				c[i+1+j]=c[i+j+1]%10;
			}
	}
	i=0;
	while(c[i]==0)i++;  //处理最高位为0的情况
	for(;i<len;i++){
		printf("%d",c[i]);
	}
}

void numfactorial(int n)  //阶乘
{
	if(n<=0)
		return;
	int res[1000];
	int cur=0;
	res[0]=1;
	int i=2,j;
	int pos=1;
	int carry=0;
	for(i=2;i<=n;++i)  
	{	
		carry=0;  //进位
		for(j=1;j<=pos;++j)
		{
			int tmp=i*res[j-1]+carry;
			res[j-1]=tmp%10;
			carry=tmp/10;
		}
		while(carry)
		{
			res[++pos-1]=carry%10;
			carry/=10;
		}
	}
	for(i=pos-1;i>=0;--i)
		cout<<res[i];
	cout<<endl;
}

int main()
{
	numfactorial(6); 
	int n=1000;
	int a=3556390;
	int b=2478389;
	numadd(a,b);
	char *t1=new char[50];
	char *t2=new char[50];
	sprintf(t1,"%d",a);
	sprintf(t2,"%d",b);
	nummulti(t1,t2);
	delete []t1;
	delete []t2;
	system("pause");
	return 0;
}


大数相加相乘及阶乘