[高精度+模板] 高精度整数加、减、乘、除模板

1. 前言




高精度加减乘除模板,可能会在求方案数、求组合数等情况下遇到,C++ 整形范围:

整型数范围
int8-128 ~ 127
uint80 ~ 256
int16-32768 ~ 32767
uint160 ~ 65535
int32-2147483648 ~ 2147483647
uint320 ~ 4294967295
int64-9223372036854775808 ~ 9223372036854775807
uint640 ~ 18446744073709551615

有以下几个模板:

  • 高精度加法:两个大整数相加
  • 高精度减法:两个大整数相减
  • 高精度乘法:两个大整数相乘、一个大整数乘以一个整数
  • 高精度触发:一个大整数除以一个整数

在此高精乘法与高精除法其实一般不会真有两个大整数直接进行运算,一般情况下是一个大整数配合一个正常的整数来做,其中除法最为复杂,所以用得少,我也没有对其进行整理。

2. 数据输入处理

大整数均存储在 vector 中,且在 vector 中的低位存放大整数的最高位,即逆序存储,主要目的是方便最后进位的处理

以下为处理大整数的输入代码:

{
    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');
}

注意: 大整数输入处理是一致的,因为可能涉及到大整数间的加减乘除混合运算,届时只需要传参调用相应函数即可。

3. 高精加

模拟加法过程就行了,记得处理进位即可。没特别需要注意的点。

高精加返回和。

参见代码如下:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

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

    int t = 0;
    for (int i = 0; i < A.size() || i < B.size(); ++i) {
        if (i < A.size()) t += A[i];
        if (i < B.size()) t += B[i];
        C.push_back(t % 10);
        t /= 10;
    }
    if (t) C.push_back(1);
    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];

    return 0;
}

4. 高精减

注意需要比较下这两个大整数的大小,保证 A>=B,若不是,则交换两数再添加负号即可。

高精减返回两数较大值减去减小值的差,保证非负。

注意: 最后需要处理前导 0 问题,避免输出 0001 这类的情况。

参见代码如下:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

// 判断A>=B
bool cmp(vector<int>& A, vector<int>& B) {
    if (A.size() != B.size()) return A.size() > B.size();

    for (int i = A.size() - 1; i >= 0; --i) 
        if (A[i] != B[i]) 
            return A[i] > B[i];

    return true;
}

// 计算C=A-B,保证A>=B,A位数大于等于B
vector<int> sub(vector<int>& A, vector<int>& B) {
    vector<int> C;

    int t = 0;
    for (int i = 0; i < A.size(); ++i) {
        t = A[i] - t;
        if (i < B.size()) t -= B[i];
        C.push_back((t + 10) % 10);
        if (t < 0) t = 1;
        else t = 0;
    }
    // 消除前导0
    while (C.size() > 1 && C.back() == 0) C.pop_back();

    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');

    // 保证A>=B, 当A<B时,交换输入参数,且需要添加负号
    if (cmp(A, B)) {
        auto C = sub(A, B);
        for (int i = C.size() - 1; i >= 0; --i) cout << C[i];
    } else {
        auto C = sub(B, A);
        cout << "-";
        for (int i = C.size() - 1; i >= 0; --i) cout << C[i];
    }

    return 0;
}

5. 高精乘

给出了两种高静乘情况,高精度数乘低精度数,高精度数乘高精度数。

高精乘返回乘积。

其中高精度数乘低精度数和加法很相似。

高精度数乘高精度数,采用模拟竖式乘法实现。

参见代码如下:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

vector<int> mul(vector<int>& A, int b) {
    vector<int> C;

    int t = 0;
    for (int i = 0; i < A.size() || t; ++i) {
        if (i < A.size()) t += A[i] * b;
        C.push_back(t % 10);
        t /= 10;
    }

    while (C.size() > 1 && C.back() == 0) C.pop_back();

    return C;
}

vector<int> mul1(vector<int> &A, vector<int> &B) {
    vector<int> C(A.size() + B.size());

    for (int i = 0; i < A.size(); i++)
        for (int j = 0; j < B.size(); j++)
            C[i + j] += A[i] * B[j];

    for (int i = 0, t = 0; i < C.size() || t; i++) {
        t += C[i];
        if (i >= C.size()) C.push_back(t % 10);
        else C[i] = t % 10;

        t /= 10;
    }

    while (C.size() > 1 && C.back() == 0) C.pop_back();

    return C;
}

int main() {
    /*
    string a;
    int b;
    vector<int> A;

    cin >> a >> b;

    for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - '0');
    */


    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 = mul1(A, B);
    for (int i = C.size() - 1; i >= 0; --i) cout << C[i];


    return 0;
}

5. 高精除

只给出高精度数除以低精度数的情况,至于高精度除高精度很少用到。

高精除返回商和余数。

注意: 高精除中需要从高精数的最高位进行处理,这是与上三者不同之处。最后需要将商进行翻转保证接口一致性,且需要去除前导 0,反转后也很方便去除前导 0。

参见代码如下:

#include <iostream>
#include <algorithm>
#include <string>
#include <vector>

using namespace std;

vector<int> div(vector<int>& A, int b, int &r) {
    vector<int> C;

    r = 0;
    for (int i = A.size() - 1; i >= 0; --i) {
        r = r * 10 + A[i];
        C.push_back(r / b);
        r %= b;
    }

    reverse(C.begin(), C.end());
    while (C.size() > 1 && C.back() == 0) C.pop_back();

    return C;
}

int main() {
    string a;
    int b;
    vector<int> A;

    cin >> a >> b;

    for (int i = a.size() - 1; i >= 0; --i) A.push_back(a[i] - '0');

    int r;
    auto C = div(A, b, r);
    for (int i = C.size() - 1; i >= 0; --i) cout << C[i];
    cout << endl << r << endl;

    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
高精度算法是指能够处理超出计算机基本数据类型范围的数字运算问题的算法。常见的高精度算法有大整数乘除、高精度开方、高精度取模等。 以下是acwing的高精度算法模板: 1. 大整数法 C++ 代码: vector<int> add(vector<int> &A, vector<int> &B) { vector<int> C; int t = 0; for (int i = 0; i < A.size() || i < B.size(); i++) { if (i < A.size()) t += A[i]; if (i < B.size()) t += B[i]; C.push_back(t % 10); t /= 10; } if (t) C.push_back(1); return C; } 2. 大整数法 C++ 代码: bool cmp(vector<int> &A, vector<int> &B) { if (A.size() != B.size()) return A.size() > B.size(); for (int i = A.size() - 1; i >= 0; i--) { if (A[i] != B[i]) return A[i] > B[i]; } return true; } vector<int> sub(vector<int> &A, vector<int> &B) { vector<int> C; for (int i = 0, t = 0; i < A.size(); i++) { t = A[i] - t; if (i < B.size()) t -= B[i]; C.push_back((t + 10) % 10); if (t < 0) t = 1; else t = 0; } while (C.size() > 1 && C.back() == 0) C.pop_back(); return C; } 3. 大整数乘法 C++ 代码: vector<int> mul(vector<int> &A, int b) { vector<int> C; int t = 0; for (int i = 0; i < A.size() || t; i++) { if (i < A.size()) t += A[i] * b; C.push_back(t % 10); t /= 10; } return C; } vector<int> mul(vector<int> &A, vector<int> &B) { vector<int> C(A.size() + B.size(), 0); for (int i = 0; i < A.size(); i++) { int t = 0; for (int j = 0; j < B.size() || t; j++) { if (j < B.size()) t += A[i] * B[j]; t += C[i + j]; C[i + j] = t % 10; t /= 10; } } while (C.size() > 1 && C.back() == 0) C.pop_back(); return C; } 4. 大整数除法 C++ 代码: int cmp(vector<int> &A, vector<int> &B) { if (A.size() != B.size()) return A.size() < B.size() ? -1 : 1; for (int i = A.size() - 1; i >= 0; i--) { if (A[i] != B[i]) return A[i] < B[i] ? -1 : 1; } return 0; } vector<int> div(vector<int> &A, int b, int &r) { vector<int> C; r = 0; for (int i = A.size() - 1; i >= 0; i--) { r = r * 10 + A[i]; C.push_back(r / b); r %= b; } reverse(C.begin(), C.end()); while (C.size() > 1 && C.back() == 0) C.pop_back(); return C; } vector<int> div(vector<int> &A, vector<int> &B) { vector<int> C; for (int i = A.size() - 1; i >= 0; i--) { C.insert(C.begin(), A[i]); while (cmp(C, B) >= 0) { vector<int> t = sub(C, B); C = t; } } while (C.size() > 1 && C.back() == 0) C.pop_back(); return C; } 5. 高精度开方 C++ 代码: int cmp(vector<int> &A, vector<int> &B) { if (A.size() != B.size()) return A.size() < B.size() ? -1 : 1; for (int i = A.size() - 1; i >= 0; i--) { if (A[i] != B[i]) return A[i] < B[i] ? -1 : 1; } return 0; } vector<int> sqrt(vector<int> &A) { vector<int> C; if (A.size() % 2 == 1) A.push_back(0); for (int i = A.size() - 2; i >= 0; i -= 2) { int res = 0; for (int j = 9; j >= 0; j--) { vector<int> t = mul(C, 20); t.push_back(j * j); if (cmp(t, A) <= 0) { res = j; C.push_back(j); break; } } } reverse(C.begin(), C.end()); while (C.size() > 1 && C.back() == 0) C.pop_back(); return C; } 6. 高精度取模 C++ 代码: int mod(vector<int> &A, int b) { int r = 0; for (int i = A.size() - 1; i >= 0; i--) { r = r * 10 + A[i]; r %= b; } return r; } vector<int> mod(vector<int> &A, vector<int> &B) { vector<int> C; for (int i = A.size() - 1; i >= 0; i--) { C.insert(C.begin(), A[i]); while (cmp(C, B) >= 0) { vector<int> t = sub(C, B); C = t; } } return C; }

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ypuyu

如果帮助到你,可以请作者喝水~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值