前言
两个长度超出常规整形变量上限的大数相减,请避免使用各语言内置大数处理库,如Java.math.BigInteger等。
代码如下:
#include<bits/stdc++.h>
using namespace std;
string substract(string s1, string s2)
{
string s3;
int len1=s1.size()-1;
int len2=s2.size()-1;
string str=""; //用来储存结果
while(len1>=0&&len2>=0)
{
int t=s1[len1]-s2[len2]; //储存此位的结果
if(t<0) //如果t<0代表需要进借位
{
t+=10;
if(s1[len1-1]=='0') //如果上位等于0,则需要再往上一位借
{
int len=len1-1;
while(len--) //直到某一上位不为0
{
if(s1[len]!='0')
break;
}
for(int i=len+1;i<=len1-1;i++) //从不为0的上位的下一位到需要借位的上一位均变为9
s1[i]='9';
s1[len]--; //不为0的上位减一;
}
else //上位不为0则直接减一
s1[len1-1]--;
}
str+=t+'0'; //此位的结果储存到字符串str里
len1--;
len2--;
}
while(len1>=0) //如果len1最后不为0,把s1剩余的位数拷贝到str里
{
str+=s1[len1];
len1--;
}
int i;
reverse(str.begin(),str.end()); //因为我们是从个位开始往后存储的,所以需要给结果逆序
for(i=0;i<str.size();i++) //判断前导是否为0
if(str[i]!='0')
break;
if(i==str.size()) //如果str所有位数均为0则结果为0
return "0";
else //反之删除前导0
str.erase(str.begin(),str.begin()+i);
return str;
}
int main()
{
string s1,s2;
cin>>s1>>s2;
int flag=0;
if(s1.size()<s2.size())
{
flag=1;
string s;
s=s1;
s1=s2;
s2=s;
}
else if(s1.size()==s2.size())
{
for(int i=0;i<s1.size();i++)
{
if(s1[i] == s2[i])
continue;
if(s1[i]<s2[i])
{
flag=1;
string s;
s=s1;
s1=s2;
s2=s;
}
else
break;
}
}
if(flag==1)
{
cout<<"-";
}
string str=substract(s1,s2);
cout<<str<<endl;
return 0;
}
总结
大数相减要考虑借位,和负数的问题。仍然使用字符串来进行存储。