1、为什么需要高精度算法?
请参考如下文章:https://blog.csdn.net/papership/article/details/153468146
2、高精度乘法用于处理大整数(超过标准数据类型范围)的乘法运算。算法思路是模拟竖式乘法。
计算步骤如下:
逐位相乘:将两个数的每一位相互相乘
处理进位:将乘积结果累加到相应位置,处理进位
结果整合:将所有中间结果相加得到最终乘积
核心原理:模拟竖式与进位
高精度乘法通过将大整数拆分为单个数字存储(通常用数组),再逐位计算乘积并处理进位,具体分为 3 步:
1.存储大整数:将两个乘数分别存入数组 A 和数组 B,且数字低位在前(如 123 存为 [3,2,1]),方便从最低位开始计算。
2.逐位计算乘积:用数组 A 的第 i 位(A [i])乘以数组 B 的第 j 位(B [j]),结果存入结果数组 C 的第 i+j 位(C [i+j] += A [i] * B [j])。
3.统一处理进位:遍历结果数组 C,对每一位执行 "C [k] = C [k] % 10",进位 "C [k+1] += C [k] / 10",确保每一位都是 0-9 的数字。
关键实现要点
数组长度估算:若乘数 A 有 n 位、乘数 B 有 m 位,结果最多有 n+m 位,因此结果数组 C 的初始长度可设为 n+m,避免空间不足。
去除前导零:计算完成后,结果数组高位可能存在多余的 0(如 100*200 结果为 20000,数组高位可能有多个 0),需从最后一位向前遍历,删除所有前导零。
输入输出处理:输入时通过字符串读取大整数,再转换为 "低位在前" 的数组;输出时从结果数组的最后一位(非零位)向前打印,还原正确顺序。
3、代码实现
#include
#include
#include
#include
using namespace std;
class BigIntMultiplication {
public:
// 高精度乘法:计算 a * b
string multiply(string num1, string num2) {
// 处理特殊情况
if (num1 == "0" || num2 == "0") return "0";
int m = num1.size(), n = num2.size();
vector result(m + n, 0); // 结果最多为 m+n 位
// 从低位到高位逐位相乘
for (int i = m - 1; i >= 0; i--) {
for (int j = n - 1; j >= 0; j--) {
int mul = (num1[i] - '0') * (num2[j] - '0');
int sum = mul + result[i + j + 1]; // 加到对应位置
result[i + j + 1] = sum % 10; // 当前位
result[i + j] += sum / 10; // 进位
}
}
// 转换为字符串,跳过前导零
string res;
for (int num : result) {
if (!(res.empty() && num == 0)) { // 跳过前导零
res += to_string(num);
}
}
return res.empty() ? "0" : res;
}
// 另一种实现:更直观的竖式乘法
string multiplyDetailed(string num1, string num2) {
if (num1 == "0" || num2 == "0") return "0";
int n1 = num1.size(), n2 = num2.size();
vector<int> pos(n1 + n2, 0);
for (int i = n1 - 1; i >= 0; i--) {
for (int j = n2 - 1; j >= 0; j--) {
int product = (num1[i] - '0') * (num2[j] - '0');
int p1 = i + j, p2 = i + j + 1;
int sum = product + pos[p2];
pos[p2] = sum % 10;
pos[p1] += sum / 10;
}
}
string res;
for (int p : pos) {
if (!(res.empty() && p == 0)) {
res += to_string(p);
}
}
return res;
}
};
// 测试函数
void testMultiplication() {
BigIntMultiplication calculator;
vector<pair<string, string>> testCases = {
{"123", "45"},
{"999", "999"},
{"123456789", "987654321"},
{"0", "12345"},
{"12345", "0"},
{"1", "123456789"},
{"123456789", "1"},
{"12", "12"}
};
for (auto& testCase : testCases) {
string a = testCase.first;
string b = testCase.second;
string result = calculator.multiply(a, b);
cout << a << " * " << b << " = " << result << endl;
}
}