Bootstrap

BigInteger(大整数)

BigInteger(大整数)

实现的功能

  • 负数

  • vector动态分配内存

  • 普通整数long long, int, 字符串string赋值

  • 加法

  • 乘法

  • 重载了+,+=, *, =,-,==, >, <

实现原理

储存

把一个整数每四位分解成一段保存到vector中, 如把7842365473734分解成3734 6547 8423 7保存

加法

把每一段分别相加, 然后把超过10000的部分加到vector下一个元素中

    for (int i = 0,x = 0; x != 0 || i < s.size() || i < b.s.size(); ++i) {
        if (i < s.size()) x += s[i];
        if (i < b.s.size()) x += b.s[i];
        c.s.push_back(x % BASE);
        x /= BASE;
    }

乘法

和列竖式做乘法类似, 每段分别交叉相乘

假如BASE = 100, 计算1234 * 3421, 每段保存2位, 结果不会超过8位, 所有最多需要四段保存

A = 1234, B = 3421, C = A * B

1 0
A 12
B 34
3 2 1 0
B[0] * A[1]
B[1] * A[1] B[1] * A[0]
408 252 + 1156
C 4 22 15

类似竖式乘法, 超过BASE需要进位(多出的保存到下一个元素)

所以如果用int来保存每段数据, 要保证相乘再相加的结果依然在int范围中.

sqrt[(2 ^ 31 - 1) / 2] =32767, 所以我把BASE设为10000不会超过范围

负数

一个正整数加一个负整数可能会出现有分段为负数有分段为正数的情况

-5445843685798 + 7842365473734 = 2396521787936

按照加法函数的运算结果为

3 2 1 0
2 3965 2179 -2064

最后一段为负值, 其余段都是正数, 但是结果是正确的. 只需要把1位置上退一位给0即可, 也就是1位置上的值变为2178, 0位置上的值变为10000 - 2064 = 7936

按照上述思路我们可以写个maintain函数来维护各段的值符号相同

只需要在输出的时候调用, 因为即使符合不同, 保存的值本质上还是相同的

    void maintain() {
        if (s[s.size() - 1] > 0)
            for (int i = 0; i < s.size() - 1; ++i)
                
;