A+B Problem IV
时间限制:1000 ms | 内存限制:65535 KB
难度:3
描述
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
高精度的正实数大数加法,需要考虑的东西很多,加油,200块之路。
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<ctime>
#include<string>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#include<set>
#include<map>
#include<cstdio>
#include<limits.h>
#define MOD 1000000007
#define fir first
#define sec second
#define fin freopen("/home/ostreambaba/文档/input.txt", "r", stdin)
#define fout freopen("/home/ostreambaba/文档/output.txt", "w", stdout)
#define mes(x, m) memset(x, m, sizeof(x))
#define Pii pair<int, int>
#define Pll pair<ll, ll>
#define INF 1e9+7
#define Pi 4.0*atan(1.0)
#define lowbit(x) (x&-x)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-7;
const int MAX = 101;
using namespace std;
#define time
bool isZero(const string str) //判断小数部分字符串是否都为0
{
int num;
sscanf(str.c_str(), "%d", &num);
if(0 == num){
return true;
}
return false;
}
int main()
{
string s1, s2, s3, s4; //s1,s2代表整数部分, s3,s4代表小数部分
while(cin >> s1 >> s2){
int pos, flag = 0; //flag表示小数部分相加是否会大于等于1,大于则flag = 1, pos代表小数点的位置
pos = s1.find(".");
s3 = s1.substr(pos+1, s1.size()); //提取小数点部分
s1 = s1.substr(0, pos);
if(pos == -1){ //若没有小数点部分,则直接赋值为0
s3 = "0";
}
pos = s2.find("."); //同上
s4 = s2.substr(pos+1, s2.size());
if(pos == -1){
s4 = "0";
}
s2 = s2.substr(0, pos);
int mlen = min(s3.size(), s4.size()); //小数部分相加
if(s3.size() < s4.size()){ //以长度较长的字符串作为标准
string tmp = s3;
s3 = s4;
s4 = tmp;
}
if(s1.size() < s2.size()){ //同上
string tmp = s1;
s1 = s2;
s2 = tmp;
}
for(int i = mlen - 1; i >= 0; --i){ //小数部分相加
s3[i] += s4[i] - '0';
if(s3[i] > '9'){
if(i == 0){ //当最大的位置相加大于9
s3[i] -= 10;
flag = 1;//则整数部分+1
break;
}
s3[i] -= 10; //不是最大位置则进行进行加法
s3[i-1] += 1; //进位
}
}
int minlen = min(s1.size(), s2.size()); //整数部分相加,从s1,s2尾部开始相加,maxlen代表较长的字符串, minlen代表较短的字符串
int maxlen = max(s1.size(), s2.size());
string str = "1"; //整数部分最大位置大于9 则 +1
for(int i = minlen - 1, j = maxlen - 1; i >= 0; --i, --j){ //字符串相加
s1[j] += s2[i] - '0';
if(s1[j] > '9'){ // 大于9,分情况
if(i == 0 && j == 0){ // 两字符串长度恰好相同, 如9+1=10
if(s1[j] > '9'){ //因为怕越界,所以直接s1之前加1
s1[j] -= 10;
s1 = str + s1; // 1+XXXX
break;
}
}
else if(i == 0 && j != 0){ //两长度不一样,一样的步骤
s1[j] -= 10;
s1[j-1] += 1;
for(int k = j-1; k >= 0; --k){
if(s1[k] > '9'){
if(k == 0){ // 这里就考虑到 999+1 = 10000,思想同上
s1[k] -= 10;
string str = "1";
s1 = str + s1;
break;
}
s1[k] -= 10;
s1[k-1] += 1;
}
}
}
if(i != 0){ //因为上面if(i==0)那步break跳出循环就不下需要执行了,所以这里要加限定条件, 不然会再执行一次会出错
s1[j] -= 10;
s1[j-1] += 1;
}
}
}
// cout << s1 << endl;
if(flag == 1){ //整数部分+1 和上面差不多, 需要考虑 999+1
s1[s1.size()-1] += flag;
if(s1[s1.size()-1] > '9'){
for(int i = s1.size()-1; i >= 0; --i){
if(s1[i] > '9'){
if(0 == i){
s1[i] -= 10;
s1 = str + s1;
break;
}
s1[i] -= 10;
s1[i-1] += 1;
}
}
}
}
if(!isZero(s3)){ //判断小数部分是否为0,为0则不输出
int k = s3.size();
while(s3[--k] == '0'); //去掉多余的0
s3 = s3.substr(0, k+1);
//cout << s3 << endl;
cout << s1 << "." << s3 << endl;
}
else{
cout << s1 << endl;
}
}
return 0;
}