Openjudge 1.13 33:实数加法

33:实数加法
描述
求2个实数相加的和。
输入输出中出现的实数都有如下的形式: P1P2...Pi.Q1Q2...Qj。对于整数部分,P1P2...Pi是一个非负整数;对于小数部分,至少有一位且最后一位Qj不等于0。

输入
2行,分别是两个加数。每个加数不超过100个字符。
输出
一行输出是相应的和。数据保证一定是一个小数部分不为0的实数。


样例输入

0.111111111111111111111111111111
0.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;
}


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值