实现大数的加法、减法、乘法、除法和次幂操作需要处理好进位、借位、负数符号等问题。下面是每个操作的实现代码。
结构体定义
struct BigNum {
int num[1000];
int len;
BigNum() {
memset(num, 0, sizeof(num));
len = 0;
}
};
1. 大数加法
大数加法实现较为简单,主要处理进位问题。
BigNum add(BigNum a, BigNum b) {
BigNum c;
int carry = 0;
int maxlength = max(a.len, b.len);
for (int i = 0; i < maxlength || carry; i++) {
int n = carry;
if (i < a.len) n += a.num[i];
if (i < b.len) n += b.num[i];
c.num[i] = n % 10;
carry = n / 10;
}
c.len = maxlength + (carry > 0);
if (carry) c.num[c.len - 1] = carry;
return c;
}
2. 大数减法
减法比加法复杂一些,需要处理借位情况。
BigNum subtract(BigNum a, BigNum b) {
BigNum c;
int borrow = 0;
for (int i = 0; i < a.len; i++) {
c.num[i] = a.num[i] - borrow - (i < b.len ? b.num[i] : 0);
if (c.num[i] < 0) {
c.num[i] += 10;
borrow = 1;
} else {
borrow = 0;
}
}
c.len = a.len;
while (c.len > 1 && c.num[c.len - 1] == 0) c.len--; // 去掉前导零
return c;
}
3. 大数乘法
乘法已经在上一个回答中给出,乘法代码可以复用。
BigNum mul(BigNum a, BigNum b) {
BigNum c;
c.len = a.len + b.len;
for (int i = 0; i < a.len; i++) {
int carry = 0;
for (int j = 0; j < b.len; j++) {
int n = a.num[i] * b.num[j] + c.num[i + j] + carry;
c.num[i + j] = n % 10;
carry = n / 10;
}
c.num[i + b.len] += carry;
}
while (c.len > 1 && c.num[c.len - 1] == 0) c.len--;
return c;
}
4. 大数除法
大数除法需要用到试商法,可以先实现一个简化版本的除法。
BigNum divide(BigNum a, BigNum b) {
BigNum c, temp;
c.len = a.len;
for (int i = a.len - 1; i >= 0; i--) {
// 将每一位加入到 temp,进行除法
temp = shift_left(temp, 1);
temp.num[0] = a.num[i];
while (compare(temp, b) >= 0) {
temp = subtract(temp, b);
c.num[i]++;
}
}
while (c.len > 1 && c.num[c.len - 1] == 0) c.len--; // 去掉前导零
return c;
}
5. 大数次幂
次幂可以通过不断调用乘法实现。
BigNum power(BigNum base, int exponent) {
BigNum result;
result.num[0] = 1; // 初始结果为1
result.len = 1;
while (exponent > 0) {
if (exponent % 2 == 1) {
result = mul(result, base);
}
base = mul(base, base);
exponent /= 2;
}
return result;
}
使用大数结构
这里用 BigNum
结构来表示大数,且每个操作都可以处理超过常规整型范围的整数运算。
大数结构和打印
struct BigNum {
int num[1000]; // 每一位的数字
int len; // 数字长度
BigNum() {
memset(num, 0, sizeof(num));
len = 0;
}
};
// 打印大数
void printBigNum(const BigNum& num) {
if (num.len == 0) {
printf("0\n");
return;
}
for (int i = num.len - 1; i >= 0; i--) {
printf("%d", num.num[i]);
}
printf("\n");
}