忘记补位了/(ㄒoㄒ)/~~,我的羸弱思路:
- 将整数小数部分分别存储,然后对他们分别进行加法。
- 先加小数部分,因为小数部分可能存在进位,需要注意的是小数部分不是从最低位开始加起,而是从小数位最少的那个数的最低位开始加,举个栗子
a1=0.567,a2=0.5678
运算是从a1的最低位和a2的第三位开始的。 - 将小数部分的进位作为参数传递给整数部分,进行一次大数加法即可。
我的习惯是将一个数字1234
,以a[4]={4,3,2,1}
的形式存储在vector中,这样如果最高位有进位的话可以直接pushback。
vec sum(vec v1, vec v2, ll mod = 0) {
if (v1.size() > v2.size())swap(v1, v2);
ll l1 = v1.size(), l2 = v2.size(), res = 0;
vec v(l2);
for (int i = 0; i < l1; i++) {
res = v1[i] + v2[i] + mod;
v[i] = res % 10; mod = res / 10;
}
for (int i = l1; i < l2; i++) {
res = v2[i] + mod;
v[i] = res % 10; mod = res / 10;
}
if (mod > 0)v.push_back(mod);
return v;
}
//小数部分的加减单独处理
vec sum2(vec v1, vec v2) {
if (v1.size() > v2.size())swap(v1, v2);
ll l1 = v1.size(), l2 = v2.size(), res = 0, mod = 0;
vec v(l2);
for (int i = 0; i < l1; i++) {
res = v1[i] + v2[i + l2 - l1] + mod;
v[i + l2 - l1] = res % 10; mod = res / 10;
}
if (mod > 0)v.push_back(mod);
for (int i = 0; i < l2 - l1; i++) v[i] = v2[i];
return v;
}
int main() {
string s1, s2;
while (getline(cin, s1) && getline(cin, s2)) {
ll l1 = s1.size(), l2 = s2.size(), k1 = s1.find('.'), k2 = s2.find('.'), mod = 0;
vec v1l, v1r, v2l, v2r, vl, vr;//第一个第二个数的整数,小数部分分别存储
for (int i = 0; i < l1; i++) {
if (i < k1)v1l.push_back(s1[k1 - 1 - i] - '0');//整数位从个位到最高为
else if (i > k1) v1r.push_back(s1[l1 + k1 - i] - '0');//小数位从最低位到最高位
}
for (int i = 0; i < l2; i++) {
if (i < k2)v2l.push_back(s2[k2 - 1 - i] - '0');
else if (i > k2) v2r.push_back(s2[l2 + k2 - i] - '0');
}
vr = sum2(v1r, v2r); //分别求和,小数部分可能存在进位
if (vr.size() > max(l1 - k1 - 1, l2 - k2 - 1))mod = vr[vr.size() - 1], vr.pop_back();
vl = sum(v1l, v2l, mod);
reverse(vl.begin(), vl.end()); reverse(vr.begin(), vr.end());//逆序输出
for (int i = 0; i < vl.size(); i++)cout << vl[i];
cout << ".";
while (vr[vr.size() - 1] == 0)vr.pop_back();//略去小数部分末尾0
for (int i = 0; i < vr.size(); i++)cout << vr[i];
cout << endl;
}
}