📌  相关文章
📜  如何在C++中存储超过100位的非常大的数字(1)

📅  最后修改于: 2023-12-03 15:08:52.119000             🧑  作者: Mango

如何在C++中存储超过100位的非常大的数字

在C++中,原生数据类型(如int、double等)的储存范围非常有限,只能存储有限的数字。如果需要存储超过100位的非常大的数字,我们可以使用高精度数。

高精度数的概念

高精度数是指可以存储非常大的数字,并进行基本的数学运算的数据类型。它的储存方式和普通的数据类型不同,不是按固定的长度进行储存。高精度数的位数可以达到任意大,取决于计算机内存的大小。

高精度数的储存方式

高精度数可以使用数组来储存,每个元素存储一位数字。我们可以将数字按照在常规计算中从右往左的顺序存储(即低位在数组的前面,高位在数组的后面),也可以将数字按照从左往右的顺序存储(即低位在数组的后面,高位在数组的前面)。

从右往左储存

下面是一个将数字从右往左储存的示例:

//定义一个长度为100的数组,储存100位数字
int a[100];
//将数字123456789赋值给数组
a[0] = 9;
a[1] = 8;
a[2] = 7;
a[3] = 6;
a[4] = 5;
a[5] = 4;
a[6] = 3;
a[7] = 2;
a[8] = 1;
//打印数组,输出为1,2,3,4,5,6,7,8,9
for(int i = 0; i < 9; i++){
   cout << a[i] << ",";
}
cout << a[9] << endl;
从左往右储存

下面是一个将数字从左往右储存的示例:

//定义一个长度为100的数组,储存100位数字
int a[100];
//将数字123456789赋值给数组
a[9] = 9;
a[8] = 8;
a[7] = 7;
a[6] = 6;
a[5] = 5;
a[4] = 4;
a[3] = 3;
a[2] = 2;
a[1] = 1;
//打印数组,输出为9,8,7,6,5,4,3,2,1
for(int i = 9; i > 0; i--){
   cout << a[i] << ",";
}
cout << a[0] << endl;

上述代码只是一个示例,实际使用时,可以根据自己的需要来选择从右往左或从左往右储存。

高精度数的加法

高精度数的加法比起普通数据类型的加法稍微麻烦一些,需要借位的情况下会涉及到多个元素的变化。

下面是高精度数加法的代码实现:

#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 1000;
struct BigInt {
    int len, s[MAXN];
    BigInt() {
        memset(s, 0, sizeof(s));
        len = 1;
    }
    BigInt(int num) {
        *this = BigInt();
        while (num) {
            s[len++] = num % 10;
            num /= 10;
        }
    }
    BigInt(const char* num) {
        *this = BigInt();
        int l = strlen(num);
        len = l;
        for (int i = 0; i < l; i++) {
            s[i] = num[l - i - 1] - '0';
        }
    }
    BigInt operator + (const BigInt& b) const {
        BigInt c;
        c.len = 0;
        for (int i = 0, g = 0; g || i < max(len, b.len); i++) {
            int x = g;
            if (i < len) x += s[i];
            if (i < b.len) x += b.s[i];
            c.s[c.len++] = x % 10;
            g = x / 10;
        }
        return c;
    }
    void clean() {
        while (len > 1 && !s[len - 1]) len--;
    }
    BigInt operator * (const BigInt& b) {
        BigInt c;
        c.len = len + b.len;
        for (int i = 0; i < len; i++)
            for (int j = 0; j < b.len; j++)
                c.s[i + j] += s[i] * b.s[j];
        for (int i = 0; i < c.len - 1; i++) {
            c.s[i + 1] += c.s[i] / 10;
            c.s[i] %= 10;
        }
        c.clean();
        return c;
    }
    BigInt operator - (BigInt& b) {
        BigInt c;
        c.len = 0;
        for (int i = 0, g = 0; i < len; i++) {
            int x = s[i] - g;
            if (i < b.len) x -= b.s[i];
            if (x >= 0) g = 0;
            else {
                g = 1;
                x += 10;
            }
            c.s[c.len++] = x;
        }
        c.clean();
        return c;
    }
    bool operator < (const BigInt& b) {
        if (len != b.len)
            return len < b.len;
        for (int i = len - 1; i >= 0; i--) {
            if (s[i] != b.s[i])
                return s[i] < b.s[i];
        }
        return false;
    }
    bool operator > (const BigInt& b) {
        return b < *this;
    }
    bool operator <= (const BigInt& b) {
        return !(b < *this);
    }
    bool operator == (const BigInt& b) {
        return !(b < *this) && !(*this < b);
    }
    BigInt operator += (const BigInt& b) {
        *this = *this + b;
        return *this;
    }
};
ostream& operator << (ostream& out, const BigInt& x) {
    out << x.s[x.len - 1];
    for (int i = x.len - 2; i >= 0; i--) {
        out.width(1);
        out.fill('0');
        out << x.s[i];
    }
    return out;
}
istream& operator >> (istream& in, BigInt& x) {
    string s;
    if (!(in >> s))
        return in;
    x = s;
    return in;
}
int main() {
    BigInt a, b;
    cin >> a >> b;
    cout << a + b << endl;
    return 0;
}
总结

高精度数的储存和运算都比较复杂,但是通过使用结构体,我们可以更方便地实现高精度数的操作,方便了我们解决一些需要大量计算的问题,是一种不可或缺的数据类型。