大整数运算之 大整数加法、减法、乘法
其实大整数的问题都是在像我们打草稿的时候列竖式一样的,不要告诉我你不知道什么叫竖式~!其实我开始也不知道它叫这个名字;
所谓竖式,就是你打草稿算算术的方法,小学知识;比如你写 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;
}

浙公网安备 33010602011771号