C++标准库提供的基础整数类型有固定的存储位数,当需要处理的数超过这些类型的上限时,就会出现数据溢出,无法得到正确结果。高精度计算的核心思路是用字符串或者数组来存储大数的每一位,通过模拟人工计算的过程实现四则运算,从而突破数据类型的位数限制。

高精度加法实现
高精度加法的逻辑和人工列竖式计算一致,从最低位开始逐位相加,记录进位,最终得到结果。实现时需要注意两个加数的位数可能不同,需要处理前导零的问题。
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
// 高精度加法函数,返回两个大数相加的结果
string addBigNum(string a, string b) {
// 反转字符串,方便从低位开始计算
reverse(a.begin(), a.end());
reverse(b.begin(), b.end());
string result = "";
int carry = 0; // 进位标志
int lenA = a.length(), lenB = b.length();
int maxLen = max(lenA, lenB);
// 逐位计算
for (int i = 0; i < maxLen; i++) {
int numA = i < lenA ? a[i] - '0' : 0;
int numB = i < lenB ? b[i] - '0' : 0;
int sum = numA + numB + carry;
result += (sum % 10) + '0';
carry = sum / 10;
}
// 处理最后的进位
if (carry > 0) {
result += carry + '0';
}
// 反转结果得到正确顺序
reverse(result.begin(), result.end());
// 去除前导零,避免结果为0时出现问题
int start = 0;
while (start < result.length() - 1 && result[start] == '0') {
start++;
}
return result.substr(start);
}
int main() {
string num1, num2;
cin >> num1 >> num2;
cout << addBigNum(num1, num2) << endl;
return 0;
}
高精度减法实现
高精度减法需要先判断两个数的大小,保证用大数减小数,若被减数小于减数则结果为负,需要添加负号。计算时同样从低位开始逐位相减,不够减时向高位借位。
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
// 判断字符串表示的大数a是否大于等于b
bool isGreaterOrEqual(string a, string b) {
if (a.length() != b.length()) {
return a.length() > b.length();
}
return a >= b;
}
// 高精度减法,返回a减b的结果
string subBigNum(string a, string b) {
// 判断是否为负数结果
bool isNegative = false;
if (!isGreaterOrEqual(a, b)) {
isNegative = true;
swap(a, b);
}
// 反转字符串方便计算
reverse(a.begin(), a.end());
reverse(b.begin(), b.end());
string result = "";
int borrow = 0; // 借位标志
int lenA = a.length(), lenB = b.length();
// 逐位计算
for (int i = 0; i < lenA; i++) {
int numA = a[i] - '0' - borrow;
int numB = i < lenB ? b[i] - '0' : 0;
if (numA < numB) {
numA += 10;
borrow = 1;
} else {
borrow = 0;
}
result += (numA - numB) + '0';
}
// 反转结果
reverse(result.begin(), result.end());
// 去除前导零
int start = 0;
while (start < result.length() - 1 && result[start] == '0') {
start++;
}
result = result.substr(start);
// 添加负号
if (isNegative) {
result = "-" + result;
}
return result;
}
int main() {
string num1, num2;
cin >> num1 >> num2;
cout << subBigNum(num1, num2) << endl;
return 0;
}
高精度乘法实现
高精度乘法的逻辑是模拟竖式乘法,用第一个数的每一位去乘第二个数的每一位,结果按位累加,最后统一处理进位。这种方法的时间复杂度为O(n*m),其中n和m分别是两个乘数的位数。
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
// 高精度乘法,返回a乘b的结果
string mulBigNum(string a, string b) {
int lenA = a.length(), lenB = b.length();
// 结果最多有lenA+lenB位
vector<int> res(lenA + lenB, 0);
// 反转字符串方便从低位计算
reverse(a.begin(), a.end());
reverse(b.begin(), b.end());
// 逐位相乘并累加
for (int i = 0; i < lenA; i++) {
for (int j = 0; j < lenB; j++) {
res[i + j] += (a[i] - '0') * (b[j] - '0');
}
}
// 处理进位
int carry = 0;
for (int i = 0; i < res.size(); i++) {
int sum = res[i] + carry;
res[i] = sum % 10;
carry = sum / 10;
}
// 将结果转换为字符串,去除前导零
string result = "";
int idx = res.size() - 1;
while (idx >= 0 && res[idx] == 0) {
idx--;
}
if (idx < 0) {
return "0";
}
for (int i = idx; i >= 0; i--) {
result += res[i] + '0';
}
return result;
}
int main() {
string num1, num2;
cin >> num1 >> num2;
cout << mulBigNum(num1, num2) << endl;
return 0;
}
高精度除法实现
高精度除法通常指大数除以一个较小的整数,逻辑是模拟人工除法的过程,从高位到低位逐位计算商和余数,每次用当前的余数乘以10加上当前位的数字,除以除数得到商的一位,余数留到下一步计算。
#include <iostream>
#include <string>
#include <vector>
using namespace std;
// 高精度除法,返回大数a除以整数b的商,余数通过引用返回
string divBigNum(string a, int b, int &remainder) {
string result = "";
remainder = 0;
// 从高位到低位逐位计算
for (int i = 0; i < a.length(); i++) {
int current = remainder * 10 + (a[i] - '0');
result += (current / b) + '0';
remainder = current % b;
}
// 去除商的前导零
int start = 0;
while (start < result.length() - 1 && result[start] == '0') {
start++;
}
return result.substr(start);
}
int main() {
string num;
int divisor;
cin >> num >> divisor;
int remainder;
string quotient = divBigNum(num, divisor, remainder);
cout << "商: " << quotient << endl;
cout << "余数: " << remainder << endl;
return 0;
}
注意事项
- 所有输入的大数字符串需要确保不包含非数字字符,除了减法结果可能带负号。
- 处理前导零时,要避免把结果0的前导零全部去掉,导致返回空字符串。
- 如果需要进行大数除以大数的运算,需要结合高精度减法和比较逻辑实现,复杂度会更高。
- 实际开发中可以根据需求封装成类,重载加减乘除运算符,使用起来更方便。