最近做区域赛的签到题,碰到大数相加相减的问题,就不想写了,虽说以前也写过,但是奈何脑子不够用,一到关键时刻还是憋不出来;送分的题就这样没了;所以在这里补习了一下高精度大数相加减;发现用string来处理这个问题确实方便了很多;
代码主题的两个函数对数据的大小正负有一定的传入要求;但是输入的时候已经判断过输入数据,并作出了相应的调整;所以可以计算任意的两个数的和与差;
代码实现如下,
#include <bits/stdc++.h>
using namespace std;
string sum,miu;//两个的和与差;
bool compare(string str1,string str2)//比较两个字符串的大小
{
if(str1.length()==str2.length()) return str1>=str2;
else return str1.length()>=str2.length();
}
string a,b;//代表输入的两个数
//高精度加法(正数相加)
string add(string str1,string str2)
{
string str;
int len1=str1.length();
int len2=str2.length();
if(len1<len2)//首先补零把两个数的长度变为相同
for(int i=1;i<=len2-len1;i++)
str1='0'+str1;//千万不能写成str1+=‘0’;
else
for(int i=1;i<=len1-len2;i++)
str2='0'+str2;
len1=str1.length();
int temp,carry=0;
for(int i=len1-1;i>=0;i--)
{
temp=(str1[i]-'0'+str2[i]-'0'+carry);
carry=temp/10;
temp%=10;
str=char(temp+'0')+str;//同样不能写成+=的形式,并且这里要加上char要不然会编译报错
}
if(carry!=0) str=char(carry+'0')+str;
return str;
}
//高精度减法(大数减小数)
string sub(string str1,string str2)//str1大于str2
{
string str;
int temp=str1.length()-str2.length();
int carry=0;
for(int i=str2.length()-1;i>=0;i--)
{
if(str1[temp+i]<str2[i]+carry)//从最低位开始减,如果不够减就借一位
{
str=char(str1[temp+i]-str2[i]+'0'+10-carry)+str;
carry=1;
}
else
{
str=char(str1[temp+i]-str2[i]+'0'-carry)+str;
carry=0;
}
}
for(int i=temp-1;i>=0;i--)
{
if(str1[i]-carry<'0')//更新str1前面的位上的值
{
str=char(str1[i]-carry+10)+str;
carry=1;
}
else
{
str=char(str1[i]-carry)+str;
carry=0;
}
}
str.erase(0,str.find_first_not_of('0'));//去除结果中多余的前导0
return str;
}
//判断输入数据的大小,以及正负;对应做出相应的操作;
void input()
{
cin >>a>>b;
if(a[0]!='-'&&b[0]!='-')
{
sum=add(a,b);
if(compare(a,b)) miu=sub(a,b);
else miu='-'+sub(b,a);
}
else if(a[0]=='-'&&b[0]!='-')
{
a.erase(0,1);
miu='-'+add(a,b);
if(compare(a,b)) sum='-'+sub(a,b);
else sum=sub(b,a);
}
else if(a[0]!='-'&&b[0]=='-')
{
b.erase(0,1);
if(compare(a,b)) sum=sub(a,b);
else sum='-'+sub(b,a);
miu=add(a,b);
}
else
{
a.erase(0,1);
b.erase(0,1);
sum='-'+add(a,b);
if(compare(a,b))
miu='-'+sub(a,b);
else
miu=sub(b,a);
}
}
int main()
{
input();
cout <<sum<<" "<<miu<<endl;
return 0;
}