#include <iostream>
#include <vector>
#include <string>
using namespace std;
//把字串存入向量
vector<int> vecfromstring(string strnum)//把字串存入向量,个位在0元素中
{
vector<int> num;//返回长整数用的向量
char ch;
for(int i=strnum.length()-1;i>=0;--i)
//循环转换
num.push_back(strnum[i]-'0');
return num;//返回结果
}
void outvec(vector<int> vec)//输出长整数
{
for(int i=vec.size()-1;i>=0;--i)
cout<<vec[i];//存储方式是原数逆顺
}
//进位/借位调整
void checkvec(vector<int>& vec, bool blnadd)
{
int len=vec.size();
if(blnadd)//进位调整
{
for(int i=0;i<len;++i)
if(vec[i]>9)
{
if(i!=len-1)vec[i+1]++;
else
vec.push_back(1);
vec[i]-=10;
}
}
else
{
for(int i=0;i<len;++i)
if(vec[i]<0)
{
vec[i]+=10;
if(i!=len-1)vec[i+1]--;
else vec.push_back(-1);
}
}
}
//长整数相加函数,返回结果向量,参数和返回值的个位在元素0 +++
vector<int> add(vector<int> x,vector<int> y,bool blndot)
{
int lenx=x.size();//向量长度
int leny=y.size();
vector<int> min;//加数
min=lenx<leny?x:y;//以短的为加数,节省时间
vector<int> res(lenx>=leny?x:y);//被加数
if(!blndot&&x.empty()&&y.empty()){res.push_back(0);return res;}
for(int i=0;i<min.size();++i)
res[i]+=min[i];//相加
checkvec(res,true);//调整进位
return res;
}
//拆分浮点串为整数串和小数串
//
浮点串,
整数串,
小数串,
,小数点位置
void splitstring(string str,string& strint,string& strdot,int idot)
{
int len=str.length();
strint=str.substr(0,idot);
strdot=str.substr(idot+1,len-idot-1);
}
void formatdotstring(string& str,int len)
{
for(int i=0;i<len;++i)str.push_back('0');
}
string stringfromvec(vector<int> ivec)
{
string strresult="";
for(int i=ivec.size()-1;i>=0;--i)
strresult.push_back(ivec[i]+'0');
return strresult;
}
//比较两个字串数值的大小比较(返回:1大于,0等于,-1小于)
int comparevec(vector<int> ivec1,vector<int> ivec2)
{
int len1=0,len2=0;
len1=ivec1.size(),len2=ivec2.size();
if(len1>len2) return 1;
else if(len1<len2) return -1;
else
{
for(int i=len1-1;i>=0;--i)
{
if(ivec1[i]>ivec2[i])return 1;
else if(ivec1[i]<ivec2[i])return -1;
}
return 0;
}
}
vector<int> sub(vector<int> ivec1,vector<int> ivec2,bool blnint)
{
vector<int> ivecres,ivectmp;
int len1=ivec1.size(),len2=ivec2.size(),itmp;
bool blnlowzero=false;
//测试完全相等时返回0
if(comparevec(ivec1,ivec2)==0){ivecres.push_back(0);return ivecres;}
itmp=len1<len2?len1:len2;
ivecres=ivec1;//被减数为整数中的长的,小数中的前者
for(int i=0;i<itmp;++i)ivecres[i]-=ivec2[i];//减运算
checkvec(ivecres,false);//调整进位
return ivecres;
}
string adddouble(string str1,string str2)
{
//
整数向量1,整数向量2,小数向量1,小数向量2,小数向量和,整数向量和
vector<int> ivecint1,ivecint2, ivecdot1, ivecdot2,ivecdotadd, ivecintadd,ivectmp;
//
整数1,
整数2,
小数1,
小数2
string strint1,strint2,strdot1,strdot2,strintadd,strdotadd,strsubflag,strdot;
//
串1小于0,
串2小于0,
结果小于0
bool blnlowzero1=false,blnlowzero2=false,blnlowzero=false;
bool blnvec1lowzero=false, blnvec2lowzero=false;
//
串1长, 串2长, 串1小数位置,串2小数位置,串1小数长, 串2小数长,小数和的长, 最长小数长度
int len1=0,len2=0,idot1=0,
idot2=0,
lendot1=0,lendot2=0,lendotadd=0,lendotmax=0;
//去掉负号并设置标志位
if(str1[0]=='-'){str1.erase(0,1);blnvec1lowzero=true;}
if(str2[0]=='-'){str2.erase(0,1);blnvec2lowzero=true;}
//无小数但末尾有小数点时补个"0"
if(str1.find('.')==str1.length()-1)str1+='0';
if(str2.find('.')==str2.length()-1)str2+='0';
//验证或设置小数点(无小数点加 ".0")
if((idot1=str1.find('.'))==-1)
{str1.push_back('.');str1.push_back('0');idot1=str1.find('.');}
if((idot2=str2.find('.'))==-1)
{str2.push_back('.');str2.push_back('0');idot2=str2.find('.');}
//分割出整数和小数
splitstring(str1,strint1,strdot1,idot1);
splitstring(str2,strint2,strdot2,idot2);
lendot1=strdot1.size();lendot2=strdot2.size();
//格式化小数
lendotmax=lendot1>lendot2?lendot1:lendot2;//最长小数长度
//把短小数和长小数对齐(短的后面补0)
if(lendot1<lendot2)formatdotstring(strdot1,lendot2-lendot1);//格式花小数
else
formatdotstring(strdot2,lendot1-lendot2);
//转换整数,小数为向量
ivecdot1=vecfromstring(strdot1);
ivecdot2=vecfromstring(strdot2);
ivecint1=vecfromstring(strint1);
ivecint2=vecfromstring(strint2);
//小数串1,2的长度
lendot1=strdot1.length();
lendot2=strdot2.length();
if(blnvec1lowzero==blnvec2lowzero)//同号
{
lendotmax=lendot1>lendot2?lendot1:lendot2;
ivecdotadd=add(ivecdot1,ivecdot2,false);//小数相加
int iresdotheight=ivecdotadd.size()-1;//小数最高位
if(lendotmax<ivecdotadd.size())//小数最高位有向整数的进位
{
ivecdotadd.pop_back();;//进位后
++ivecint1[0];//向整数进位
}
ivecintadd=add(ivecint1,ivecint2,true);//整数相加(已经包含小数进位)
strsubflag=blnvec1lowzero?"-":"";//同号为负时输出有负号
}else//符号不同( A:-1+2=2-1 B:2+(-1)=2-1 C:-2+1=1-2* D:1+(-2)=-(2-1)* )
{
int icmp=comparevec(ivecint1,ivecint2);
if(icmp==-1)//小减大:D
{//交换
ivectmp=ivecdot1;ivecdot1=ivecdot2;ivecdot2=ivectmp;
ivectmp=ivecint1;ivecint1=ivecint2;ivecint2=ivectmp;
}
if(comparevec(ivecdot1,ivecdot2)==-1)//需要向整数借位
{
ivecdot1[ivecdot1.size()-1]+=10;
ivecint1[0]--;
}
ivecdotadd=sub(ivecdot1,ivecdot2,false);//小数减
ivecintadd=sub(ivecint1,ivecint2,true);//整数减
if(icmp==-1&&blnvec2lowzero||icmp==1&&blnvec1lowzero)strsubflag="-";
}
strintadd=stringfromvec(ivecintadd);//换成串
while(strintadd[0]=='0')strintadd.erase(0,1);//去掉整数前置0
strdotadd=stringfromvec(ivecdotadd);//换成串
while(strdotadd[strdotadd.length()-1]=='0')//去掉小数后置 0
strdotadd.erase(strdotadd.length()-1,1);
strdot=!strdotadd.empty()?".":"";//无小数时不输出小数点
if(strintadd.empty())strintadd="0";
return strsubflag+strintadd+strdot+strdotadd;
}
int main()
{
string str1, str2,stradd;
while(true)
{
cin>>str1;cin>>str2; //输入两个浮点数
stradd=adddouble(str1,str2);
cout<<stradd<<endl<<endl;
cin.get();cin.get();
}
}
以前写的一个程序,整数和小数分开处理的.
能改进,把小数和整数对阶,统一小数长度,相加,输出就行了,能少一次相加运算