高精度加法位数会增大(比最大的位数会多1位)
高精度减法位数会减小(最大会到1位)
高进度乘法位数会增大(最大不超过两数位数之和)
一.高精度加法
- 将两数的位数加’0’对齐
- 从个位开始相加,考虑进位
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
string add(string a,string b)
{
int lena=a.length(),lenb=b.length();
//将a,b加‘0’对齐。如a=123,b=56789。补齐后a=00123
if(lena<lenb)
{
for(int i=1;i<=lenb-lena;i++)
a='0'+a;
}
else
for(int i=1;i<=lena-lenb;i++)
b='0'+b;
int len=max(lena,lenb);
string ans(len,'0');
int tmp=0; //存放加数
//从个位开始加
for(int i=len-1;i>=0;i--)
{
tmp+=(a[i]-'0')+(b[i]-'0'); //28
ans[i]=tmp%10+'0'; //ans[i]=8;
tmp/=10; //tmp=2
}
//如果有进位
if(tmp) {ans=char(tmp+'0')+ans;}
return ans;
}
int main()
{
string a,b;
cin>>a>>b;
cout<<add(a,b);
return 0;
}
注:
- for()循环从 i=len-1开始,因为后面代表个位
- ans[i]=tmp%10+‘0’ 记得加字符’0’
- char(tmp+‘0’) 记得用char强制化,因为(tmp+‘0’)仍为int型
二.高精度减法
- 将两数的位数加’0’对齐
- 从个位开始相减,考虑借位
- 最终答案去掉多余的0
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
//只讨论a>b的情况
string sub(string a,string b)
{
int lena=a.length(),lenb=b.length();
//将a,b位数加'0'对齐
for(int i=1;i<=lena-lenb;i++)
b='0'+b;
lenb=lena;
int len=max(lena,lenb);
string ans(len,'0');
//从个位开始
for(int i=lena;i>=0;i--)
{
if(a[i]>=b[i])
ans[i] = a[i]-b[i]+'0';
//借位
else
{
a[i-1] -= 1;
ans[i] = a[i]-b[i]+10+'0';
}
}
if(ans.find_first_not_of('0')!=-1)
return ans.substr(ans.find_first_not_of('0'));
else
return "0";
}
int main()
{
string a,b;
cin>>a>>b;
cout<<sub(a,b);
return 0;
}
注:
- sub()函数中,ans可能为0,若如此find_first_not_of(‘0’)函数为-1。调用ans.sub()会出错。因此要分情况。
- 该sub()函数中只讨论a>b;若a<b,只需输出“-”号,同时交换a,b的值,在按照a>b的情况写。
三、高精度乘法
与高精度加法只需一个变量存储进位不同,乘法需要一个数组;
乘法规律:c[i + j] += a[i] * b[j];
#include<iostream>
#include<string>
#include<algorithm>
#include<cstring>
using namespace std;
string mul(string a, string b)
{
reverse(a.begin(),a.end());
reverse(b.begin(),b.end());
int lena = a.length(), lenb = b.length();
int len = lena + lenb;
string ans;
int tmp[len];
memset(tmp,0,sizeof(tmp));
//规律 c[i+j] += a[i] * b[j]
for(int i=0;i<lena;i++)
for(int j=0;j<lenb;j++)
tmp[i+j] += (a[i]-'0') * (b[j]-'0');
//处理进位
for(int i=0;i<len;i++)
{
tmp[i+1] += tmp[i]/10;
ans+= (tmp[i]%10+'0');
}
reverse(ans.begin(),ans.end());
return ans.substr(ans.find_first_not_of('0'));
}
int main()
{
string a,b;
cin>>a>>b;
if(a=="0"||b=="0")
{
cout<<"0";
return 0;
}
else
cout<<mul(a,b);
return 0;
}