33:实数加法
描述
求2个实数相加的和。
输入输出中出现的实数都有如下的形式: P1P2...Pi.Q1Q2...Qj。对于整数部分,P1P2...Pi是一个非负整数;对于小数部分,至少有一位且最后一位Qj不等于0。
输入
2行,分别是两个加数。每个加数不超过100个字符。
输出
一行输出是相应的和。数据保证一定是一个小数部分不为0的实数。
0.111111111111111111111111111111
样例输出
描述
求2个实数相加的和。
输入输出中出现的实数都有如下的形式: P1P2...Pi.Q1Q2...Qj。对于整数部分,P1P2...Pi是一个非负整数;对于小数部分,至少有一位且最后一位Qj不等于0。
输入
2行,分别是两个加数。每个加数不超过100个字符。
输出
一行输出是相应的和。数据保证一定是一个小数部分不为0的实数。
样例输入
0.1111111111111111111111111111110.111111111111111111111111111111
样例输出
0.222222222222222222222222222222
题目分析:
本题与其他大整数加法不同,它的加数中含有小数部分,所以在开始运算之前需分离整数和小数。对于整数加法,我们需要从高位至低位倒序储存,但是对于小数部分,由于是由十分位、百分位、千分位向下排列,所以储存时直接顺向储存即可。我本题中先运算的是整数部分,但先运算小数部分应该更加简洁。小数部分需要从最后一位向前加,注意碰到进位时,向前一位进位,但如果小数的十分位需要进位,那么需要进到整数的个位。整数部分的前导零必须去掉,出现前导零的情况通常是整数部分为0的情况,此时整数部分只输出一个0,所以我先用一个“for”循环判断整数部分是否为0,再进行输出。由于题目已经给出小数部分不为0,所以可以直接输出小数点和小数部分。
程序样例(仅供参考,非最优):
#include<cstdio>
#include<cstring>
int main()
{
char a[105],b[105];
gets(a);
gets(b);
int lena=strlen(a),lenb=strlen(b),zsa[105]={},zsb[105]={},xsa[105]={},xsb[105]={};
int szsa=0,szsb=0,sxsa=0,sxsb=0;
//分离倒序a
for(int h=0,oa=1;h<lena;h++)
{
if(a[h]=='.')
oa=0;
else
oa? zsa[szsa++]=a[h]-'0':xsa[sxsa++]=a[h]-'0';
}
int sy[105]={};
for(int i=0,j=szsa-1;i<szsa;i++,j--)
sy[i]=zsa[j];
for(int i=0;i<szsa;i++)
zsa[i]=sy[i];
//分离倒序b
for(int g=0,ob=1;g<lenb;g++)
{
if(b[g]=='.')
ob=0;
else
ob? zsb[szsb++]=b[g]-'0':xsb[sxsb++]=b[g]-'0';
}
memset(sy,0,sizeof(sy));
for(int i=0,j=szsb-1;i<szsb;i++,j--)
sy[i]=zsb[j];
for(int i=0;i<szsb;i++)
zsb[i]=sy[i];
//整数加法
int max_zs=szsa>szsb? szsa:szsb,endzs[105]={},sendzs;
sendzs=max_zs+2;
for(int i=0;i<max_zs;i++)
{
endzs[i]+=zsa[i]+zsb[i];
if(endzs[i]>=10)
{
endzs[i]-=10;
endzs[i+1]++;
}
}
while(endzs[sendzs]==0 && sendzs>1)
sendzs--;
//小数加法
int max_xs=sxsa>sxsb? sxsa:sxsb,endxs[105]={},sendxs;
sendxs=max_xs+1;
for(int i=max_xs-1;i>=0;i--)
{
endxs[i]+=xsa[i]+xsb[i];
if(endxs[i]>=10)
{
if(i==0)
{
endzs[0]++;
endxs[0]-=10;
}
else
{
endxs[i-1]++;
endxs[i]-=10;
}
}
}
while(endxs[sendxs]==0 && sendxs>0)
sendxs--;
//小数再判进位
for(int i=sendxs-1;i>=0;i--)
{
if(endxs[i]>=10)
{
endxs[i]-=10;
if(i>=1)
endxs[i-1]++;
else
endzs[0]++;
}
}
//整数再判进位,判断是否为0
bool zero=true;
for(int i=0;i<sendzs;i++)
{
if(endzs[i]!=0)
zero=false;
if(endzs[i]>=10)
{
endzs[i+1]++;
endzs[i]-=10;
}
}
sendzs+=2;
while(endzs[sendzs]==0 && sendzs>1)
sendzs--;
//输出
if(zero)
printf("%d",0);
else
for(int i=sendzs;i>=0;i--)
printf("%d",endzs[i]);
for(int i=0;i<=sendxs;i++)
{
if(i==0)
printf(".");
printf("%d",endxs[i]);
}
return 0;
}