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)