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

来源:互联网 发布:中国黑人数量知乎 编辑:程序博客网 时间:2024/06/10 16:15

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

所谓竖式,就是你打草稿算算术的方法,小学知识;比如你写 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;elses[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);elsesub(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;}



	
				
		
原创粉丝点击