Description
话说,经过了漫长的一个多月,小明已经成长了许多,所以他改了一个名字叫“大明”。这时他已经不是那个只会做100以内加法的那个“小明”了,现在他甚至会任意长度的正小数的加法。现在,给你两个正的小数A和B,你的任务是代表大明计算出A+B的值。
Input
本题目包含多组测试数据,请处理到文件结束。每一组测试数据在一行里面包含两个长度不大于400的正小数A和B。
Output
请在一行里面输出输出A+B的值,请输出最简形式。
Sample Input
1.1 2.9
1.1111111111 2.3444323343
1 1.1
Sample Output
4
3.4555434454
2.1
Solution
高精度加法,注意前置0和小数点后置0以及整数不带小数点
Code
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 802
void deal(char c[],int num[])//将一个数整数部分放在数组前400位,小数部分放在数组后400位
{
int len=strlen(c);
int flag=-1;//记录小数点位置
for(int i=0;i<len;i++)
if(c[i]=='.')
{
flag=i;
break;
}
if(flag==-1)//没有小数点
for(int i=len-1,j=399;i>=0;i--,j--)//整数部分放在数组前400位
num[j]=c[i]-'0';
else//有小数点
{
for(int i=flag+1,j=401;i<len;i++,j++)//小数部分放在数组后400位
num[j]=c[i]-'0';
for(int i=flag-1,j=399;i>=0;i--,j--)//整数部分放在数组前400位
num[j]=c[i]-'0';
}
}
void solve(int a[],int b[])//a+b
{
int ans[maxn]={0},k=0;//初始化,k表示进位值
for(int i=800;i>400;i--)//先加小数部分
{
ans[i]=(a[i]+b[i]+k)%10;
k=(a[i]+b[i]+k)/10;
}
a[399]+=k;//进位
k=0;
for(int i=399;i>=0;i--)//再加整数部分
{
ans[i]=(a[i]+b[i]+k)%10;
k=(a[i]+b[i]+k)/10;
}
ans[400]=-1;
int l=0,r=800;
while(ans[l]==0)l++;//去掉整数部分前置0
while(ans[r]==0)r--;//去掉小数部分后置0
if(l==400&&r==400)//特判结果为0
{
printf("0");
}
else if(l==400&&r!=400)//整数部分为0
{
printf("0.");
for(int i=401;i<=r;i++)
printf("%d",ans[i]);
}
else if(l!=400&&r==400)//小数部分为0
{
for(int i=l;i<400;i++)
printf("%d",ans[i]);
}
else//都不为0
{
for(int i=l;i<400;i++)//先输出1整数部分
printf("%d",ans[i]);
printf(".");//输出小数点
for(int i=401;i<=r;i++)//输出小数部分
printf("%d",ans[i]);
}
printf("\n");
}
int a[maxn],b[maxn];
int main()
{
char temp[maxn];
while(~scanf("%s",temp))
{
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
deal(temp,a);
scanf("%s",temp);
deal(temp,b);
solve(a,b);
}
return 0;
}