A+B Problem IV
-
描述
- acmj最近发现在使用计算器计算高精度的大数加法时很不方便,于是他想着能不能写个程序把这个问题给解决了。
-
输入
- 包含多组测试数据
每组数据包含两个正数A,B(可能为小数且位数不大于400)
输出 - 每组输出数据占一行,输出A+B的结果,结果需要是最简的形式。 样例输入
-
1.9 0.1 0.1 0.9 1.23 2.1 3 4.0
样例输出 -
2 1 3.33 7
一道高精度加法的题目。
由于数据中可能既有小数又有整数,所以我把整数变成小数(后面加".0"),从而化为两个小数相加的问题。
找小数点的时候,先判断它是否有末尾0,把末尾0先消去(最少保留一个)。
然后把小数点对齐,按照A+B(二)的做法先把数组倒置,然后对应位相加。
#include<cstdio> #include<cstring> #define max(a,b) a>b?a:b struct Num{ int len,back;//len 为 字符串长度 back 为小数的位数 char num[800]; }A,B; void swap(char &a,char &b){ char t=a; a=b; b=t; } void Init(Num &a){ // 去除小数末尾的零,但至少有一位小数 a.len=strlen(a.num); char *p=strchr(a.num,'.'); if(p==NULL){ //如果是整数,补充小数点和一位小数 a.num[a.len++]='.'; a.num[a.len++]='0'; a.back=1; } else{ int point_loc=p-a.num;//记录小数点的位置,去除小数末尾的零 for(int i=a.len-1;i>=point_loc+2;i--){ if(a.num[i]!='0') break; a.len--; } a.back=a.len-1-point_loc; } } void Reverse(Num &a){ for(int i=0;i<a.len-1-i;i++) swap(a.num[i],a.num[a.len-1-i]); } void add(Num &a,Num &b){ Reverse(a); int sub=a.back-b.back;//小数位数的差值 int max_len=max(b.len+sub,a.len);//两个数中最大的位数 memset(a.num+a.len,'0',max_len-a.len+1);//反转高位补零。 for(int i=sub;i<max_len;i++){//模拟每一位相加 if(a.num[i]=='.') continue; int b_loc=b.len-1-(i-sub); if(b_loc>=0) a.num[i]+=b.num[b_loc]-'0'; if(a.num[i]>'9'){ a.num[i+1]=='.'?a.num[i+2]++ : a.num[i+1]++; a.num[i]-=10; } } int min_loc;//记录小数部分不为零的位置。 for(min_loc=0;a.num[min_loc]=='0';min_loc++); max_len= a.num[max_len]=='0' ? max_len-1 : max_len;//如果最高位有进位 输出。 min_loc=a.num[min_loc]=='.' ? min_loc+1 : min_loc;//如果小数为只有一个小数点,则不必要输出 for(int i=max_len;i>=min_loc;i--) printf("%c",a.num[i]); printf("\n"); } int main(){ while(scanf("%s%s",A.num,B.num)!=EOF){ Init(A); Init(B); A.back>B.back?add(A,B):add(B,A); } }
- 包含多组测试数据
439



被折叠的 条评论
为什么被折叠?



