//土尔逊Torson 编写于2023/4/20 #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstdio> #include <cstring> #include <string> #include <algorithm> using namespace std; #define _for(i, a, b) for (int i = a; i < b; ++i) #define mem(a, b) memset(a, b, sizeof(a)) //有两种方式实现这个精度计算,一种是利用逆置存储计算过程,一种是按照手算计算思维实现 //区别在于 bign change()、bign add()、void print()函数的具体实现方式的不同 /* 第一种实现方式 //将字符串转换为大整数 bign change(string s) { bign c; int len = s.length(); int pos = s.find('.'); _for(i, 0, len) { if (i == pos) continue; i < pos ? c.in[c.ilen++] = s[pos - i - 1] - '0' : c.fn[c.flen++] = s[len - i + pos] - '0'; } return c; } //高精度a + b bign add(bign a, bign b) { bign c; int carry = 0; //对小数部分进行处理 _for(i, 0, a.flen) { int tmp = a.fn[i] + b.fn[i] + carry; c.fn[c.flen++] = tmp % 10; carry = tmp / 10; } //对整数部分进行处理 _for(i, 0, max(a.ilen, b.ilen)) { int tmp = a.in[i] + b.in[i] + carry; c.in[c.ilen++] = tmp % 10; carry = tmp / 10; } if (carry != 0) { c.in[c.ilen++] = carry; } return c; } //输出bign void print(bign a) { //打印整数部分 for (int i = a.ilen - 1; i >= 0; --i) { printf("%d", a.in[i]); } //打印小数点 printf("."); //打印小数部分 for (int i = a.flen - 1; i >= 0; --i) { printf("%d", a.fn[i]); } printf("\n"); } */ // 第二种实现方式 struct bign { int ilen; //整数部分的长度 int flen; //小数部分的长度 int in[1010]; //整数部分数字 int fn[1010]; //小数部分数字 bign() { ilen = 0, flen = 0; mem(in, 0), mem(fn, 0); } }; //让2个浮点数的小数部分长度相同 void cmp(string &a, string &b) { int lena = a.length(), lenb = b.length(); int posa = a.find('.'), posb = b.find('.'); lena -= posa, lenb -= posb; lena < lenb ? a.append(lenb - lena, '0') : b.append(lena - lenb, '0'); } //将字符串转换为大整数 bign change(string s) { bign c; int len = s.length(); int pos = s.find('.'); _for(i, 0, len) { if (i == pos) { continue; } else { i < pos ? c.in[c.ilen++] = s[i] - '0' : c.fn[c.flen++] = s[i] - '0'; } } return c; } //高精度a + b bign add(bign a, bign b) // 按照手算带小数的传统计算方式实现精度加法计算 { bign c; c.flen = max(a.flen, b.flen); c.ilen = max(a.ilen, b.ilen); int carry = 0; //对小数部分进行处理 int r = (c.flen - 1); for(int i = max(a.flen,b.flen) - 1; i >= 0; --i) { int tmp = a.fn[i] + b.fn[i] + carry; c.fn[r--] = tmp % 10; carry = tmp / 10; } //对整数部分进行处理 int q; a.ilen > b.ilen ? q = b.ilen - 1 : q = a.ilen - 1; for (int i = max(a.ilen, b.ilen) - 1; i >= 0; --i) { if (a.ilen > b.ilen) { if (q >= 0) { int tmp = a.in[i] + b.in[q--] + carry; c.in[i] = tmp % 10; carry = tmp / 10; } else if(q<0){ int tmp = a.in[i] + carry; c.in[i] = tmp % 10; carry = tmp / 10; } } else if (a.ilen < b.ilen) { if (q >= 0) { int tmp = a.in[q--] + b.in[i] + carry; c.in[i] = tmp % 10; carry = tmp / 10; } else if(q<0){ int tmp = b.in[i] + carry; c.in[i] = tmp % 10; carry = tmp / 10; } } else if (a.ilen == b.ilen) { int tmp = a.in[i] + b.in[i] + carry; c.in[i] = tmp % 10; carry = tmp / 10; } } if (carry != 0) { c.ilen++; int g = c.ilen - 1, h = c.ilen - 2; for (int i = c.ilen - 1; i >= 1; i--) { c.in[i] = c.in[h--]; } c.in[0] = carry; } //返回值 return c; } //输出bign void print(bign a) { //打印整数部分 for (int i = 0; i <= a.ilen - 1; ++i) { printf("%d", a.in[i]); } //打印小数点 printf("."); //打印小数部分 for (int i = 0; i <= a.flen - 1; ++i) { printf("%d", a.fn[i]); } printf("\n"); } //练习两种方式有助于发散思维 int main() { string s1, s2; while (cin >> s1 >> s2) { cmp(s1, s2); bign a = change(s1), b = change(s2); print(add(a, b)); } system("pause"); return EXIT_SUCCESS; } // 64 位输出请用 printf("%lld")