高精度加减法(附源代码)

#include<iostream>
#include<vector>
using namespace std;


vector<int> add(vector<int>& A, vector<int>& B) {

    if (A.size() < B.size()) return add(B, A);//保证A的位数大于B
    int t = 0;

    vector<int> C;
    for (int i = 0; i < A.size(); i++) {

        t += A[i];
        if (i < B.size())t += B[i];//如果B加到最后一位,则不再加
        C.push_back(t % 10);
        t /= 10;
    }
    if (t) C.push_back(t);
    return C;
}

int main() {


    string a, b;
    vector<int> A, B;
    cin >> a >> b;
    for (int i = a.size() - 1; i >= 0; i--)A.push_back(a[i] - '0');
    for (int i = b.size() - 1; i >= 0; i--)B.push_back(b[i] - '0');
    auto C = add(A, B);

    for (int i = C.size() - 1; i >= 0; i--) cout << C[i];
    cout << endl;
    return 0;
}

该算法的适用场景是超大数的加法运算

整体思路就是回想自己做加法时的步骤就可以了.

以下有几个值得注意的点:

1.保证A的位数大于B

2.存储算法时,从低位开始存储,(虽然会导致之后的高精度除法需要稍微多一些的操作,但是数据在计算的过程中应该遵守其源数据不变的原则)


#include<iostream>
#include<vector>

using namespace std;
bool sign;

vector<int> sub(vector<int>& A, vector<int>& B, bool sign) {

    vector<int> C;

    if (A.size() < B.size())return sub(B, A, false);//保证A>B
    else if (A.size() == B.size()) {
        for (int i = A.size() - 1; i >= 0; i--) {
            if (A[i] < B[i])return sub(B, A, false);
            else if (A[i] > B[i])break;
        }
    }
    int t = 0;
    for (int i = 0; i <= A.size() - 1; i++) {
        t = A[i] - t;//减去借位
        if (i < B.size())t -= B[i];
        C.push_back((t + 10) % 10);//若t<0则借位,若t>0,则与%10抵消
        if (t < 0) t = 1;
        else t = 0;
    }
    while (C.size() > 1 && C.back() == 0)C.pop_back();
    if (!sign)C.push_back(-1);
    return C;
}

int main()
{
    sign = true;
    string a, b;
    vector<int> A, B;
    cin >> a >> b;
    for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');
    for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');

    vector<int> C;

    C = sub(A, B, sign);
    if (C.back() == -1) {

        cout << "-";
        C.pop_back();
    }
    for (int i = C.size() - 1; i >= 0; i--) cout << C[i];
    cout << endl;
    return 0;
}

该算法的适用场景是超大数的减法运算

需要注意的有以下几点:

1.该算法会存在符号问题,我们需要保证A大于B,如果存在调换,我们就会把最终结果加上负号

减法会比加法稍微复杂一些,本算法没有考虑两个负数相减的情况是因为,在任何情况下的加减的问题,都可以把问题转化成|A|+|B|或者 |A|-|B|的形式,这个问题是可以通过对输入端的判断来解决的,所以该算法不存在漏洞


版权声明:本文为qq_52810376原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。