大整数运算之 大整数加法、减法、乘法

其实大整数的问题都是在像我们打草稿的时候列竖式一样的,不要告诉我你不知道什么叫竖式~!其实我开始也不知道它叫这个名字;

所谓竖式,就是你打草稿算算术的方法,小学知识;比如你写 11+9:

11

+   9

----------

20


数A,B,求和,求差;数的长度不超过1000;

贴个代码,先输入一个数,代表数据的组数n,然后输入n组A B



#include <iostream>
using namespace std;
#define base 4
#define M 10000 
char s1[1000],s2[1000];
int A[251],B[251],sum[251];
int max(int a,int b)
{
	return a>b?a:b;
}
void  trans(char *str, int *s)  //将一串数字字符 转化为大整数 
{
	int i,k = 1;
	int flag = strlen(str) - base;
	for(i = flag; i >= 0; i -= base,k++)
	{
		s[k] = str[i] - '0';
		for(int j = i+1; j < i + base; j++)
		{
			s[k] = s[k]*10 + str[j]-'0';
		}
	}
	i += base;
	s[k] = 0;
	for(int j = 0; j < i; j++)
	{
		s[k] = s[k]*10 + str[j] - '0';
	}
	if(s[k])
		s[0] = k;
	else
		s[0] = k-1;
} 

void prin(int *num)
{
	printf("%d",num[num[0]]);
	for(int i = num[0] - 1; i >= 1; i--)
	{
		printf("%04d",num[i]);
	}
}

void copy(int *a,int *b)  //b复制给a 
{
	for(int i = 0; i <= b[0]; i++)
		a[i] = b[i];
}
int comp(int *a, int *b)  //比较大整数大小,a>b返回1,a<b返回-1,相等返回0 
{
	if(a[0] > b[0])return 1;
	if(a[0] < b[0])return -1;
	for(int i = a[0]; i >= 1 ; i--)
	{
		if(a[i] > b[i])return 1;
		if(a[i] < b[i])return -1;
	}
	return 0;
} 
void add(int *A,int *B, int *sum)
{
	int i,d[1000];
	if((B[0]==1)&&(B[1]==0)){copy(sum,A);return;}
	if((A[0]==1)&&(A[1]==0)){copy(sum,B);return;}
	if (A[0] >= B[0]) { copy(sum,A);copy(d,B);} 
	else { copy(sum,B);copy(d,A);}
	
	//转换为sum + d(即A、B的最大值和最小值);最终结果为sum 
	sum[sum[0] + 1] = 0;   //存放可能出现的进位 
	for (i = 1; i <= d[0]; i++) //处理位数相同的 
	{
	    sum[i]+=d[i];     
	    if (sum[i]>=M)
		{
	      sum[i]-=M;
		  sum[i+1]++; 
		} 
	}    
	for (; i <= sum[0]; i++)  //处理A、B中大的多出来的位数 
	{
		if(sum[i]>=M) 
		{
			sum[i] -= M;
			sum[i+1]++;
		} 
		else break; 
	}
	if (sum[sum[0]+1]>0)sum[0] = sum[0] + 1;
}

void sub(int *A, int *B, int *ans)//大整数相减,默认A大于B 
{
	int D[1000];
	int i; 
	copy(ans,A);
	copy(D,B);
		
	for(i = 1; i <= D[0]; i++)
	{
		if(ans[i] < D[i])
		{
			ans[i] += M;
			ans[i+1]--;
		}
		ans[i] -= D[i];	
	}
	for(; i < ans[0]; i++)
	{
		if(ans[i]<0)
		{
			ans[i]+=M;
			ans[i+1]--;
		}
		else break;
	}
	if(!ans[ans[0]])
		ans[0]--;	
} 

void mult(int *a,int *b,int *ans)
{
	int k= a[0]+b[0]-1;//Base<=10000 

	/*m位数 *n位数 = m+n-1位 或 m+n 位数  */
	
	for(int i=0;i<=k;i++)
		ans[i]=0;
	// step 1:a[1],a[2]....,a[m]
	//         b[1]
	//         c[1],c[2],...,c[m] 
	//step 2: a[1],a[2]....,a[m]
	//              b[2]
	//        c[1],c[2],...,c[m] 
	//step 3:... ...
	
	for(int i=1;i<=b[0];i++) //b[] 在乘法竖式下方
	{ 
		int now_i = i;
		if(b[i])   //b[i]为0时,ans[now_i]也为0,不考虑 
		for(int j=1;j<=a[0];j++,now_i++)  //a[]在乘法竖式上方
		{
			ans[now_i]+=a[i]*b[j];
			if(ans[now_i]>=M)   //求余进位 
			{
				ans[now_i+1]+=ans[now_i]/M;
				ans[now_i]%=M;
			}
		}
	}
	//再次求余进位,
	// 2  9999 9999
	// 2  9999 9999
	//--------------
	//step 1: 9999 9999
	//        9999  
	//        0001  0002 9997 进位余数9999  然后是(9999+9999)*9999,99970002     
	if(ans[k+1])
           k++;
	ans[0]=k;
}

int main()
{
	int T,k = 1;
	cin>>T;
	while(T--)
	{
		cin.get();
		scanf("%s%s",s1,s2);
		trans(s1,A); trans(s2,B);
		add(A,B,sum);
		printf("Case %d:\n",k);
		prin(A);
		cout<<" + ";
		prin(B);
		cout<<" = ";
		prin(sum);
		cout<<endl;
		
		int fl = 1;
		if(comp(A,B)!=-1)
			fl=0,sub(A,B,sum);
		else
			sub(B,A,sum);
		printf("Case %d:\n",k);
		prin(A);
		cout<<" - ";
		prin(B);
		cout<<" = ";
		if(fl)cout<<"-";
		prin(sum);
		cout<<endl;

		mult(A,B,sum);
		printf("Case %d:\n",k++);
		prin(A);
		cout<<" * ";
		prin(B);
		cout<<" = ";
		prin(sum);
		cout<<endl;
		if(T)
			cout<<endl;
	}
	return 0;
}




posted @ 2013-01-10 17:29  简洁是智慧的灵魂  阅读(261)  评论(0)    收藏  举报