C++ 高精度整数乘法实现(大数乘法逐位模拟)
摘要
在 C++ 中,当两个整数的位数超过内置整型范围时(如 long long 也只能表示约 19 位数字),我们需要使用字符串或数组来模拟大数的运算。本文将讲解如何实现大整数乘法,通过逐位模拟手工竖式乘法来实现任意长度整数的乘法计算,并给出可直接运行的示例代码和详细解析。
一、问题描述
给定两个非负整数 a 和 b(以字符串形式表示),要求计算它们的乘积并返回字符串形式的结果。
例如:
输入: a = "12345", b = "678"
输出: "8369910"
注意 :如果任意一个输入为 "0",输出必须为 "0"。
二、算法思想
高精度整数乘法主要模拟我们手工计算的竖式乘法:
-
逐位相乘:
- 外层循环从第二个数(
b)的最低位到最高位遍历。 - 内层循环从第一个数(
a)的最低位到最高位遍历。 - 将当前位的乘积加上上一次的进位以及结果数组当前位置已有的值。
- 外层循环从第二个数(
-
进位处理:
- 每一位乘法的结果可能大于 10,需要向高位进位。
- 每轮外层循环结束后,如果还有进位,需要写入数组高位。
-
移位加法:
- 外层循环每进行一轮,就相当于乘 b 的当前位对 a 的整个乘积,然后按位数移动(类似手算竖式,乘 b 的个位不移,十位向左移一位,百位移两位)。
-
最终结果:
- 通过整型数组保存每一位的结果,最后转换为字符串。
- 去掉前导零。
三、代码实现

cpp
#include <iostream>
#include <string>
#include <vector>
typedef long long ll;
// 将数组转为字符串,并去掉前导零
std::string num_arr_to_string(std::vector<int> arr){
std::string result("");
bool begin = false;
for (int c: arr){
if (c != 0) begin = true;
if (begin) result += std::to_string(c);
}
return result.empty() ? "0" : result; // 注意处理全零的情况
}
// 判断字符串是否全为零
bool is_zero_str(const std::string &a){
for (char c: a) if (c != '0') return false;
return true;
}
// 大整数乘法
std::string big_num_multi(const std::string &a, const std::string &b){
if (is_zero_str(a) || is_zero_str(b)) return "0";
int n = a.size();
int m = b.size();
int max_len = n + m; // 最多 n+m 位
std::vector<int> arr(max_len, 0);
for (int i = m - 1; i >= 0; i--){ // b 的每一位
int jin = 0; // 每轮外层循环的进位
int idx = max_len - (m - i); // 当前外层位对应数组的索引
for (int j = n - 1; j >= 0; j--){ // a 的每一位
int b_num = b[i] - '0';
int a_num = a[j] - '0';
int multi_num = b_num * a_num + jin + arr[idx]; // 乘积 + 进位 + 数组已有值
arr[idx] = multi_num % 10;
jin = multi_num / 10;
idx--;
}
if (jin) arr[idx] = jin; // 外层循环结束后剩余进位
}
return num_arr_to_string(arr);
}
int main(){
std::string a, b;
std::cin >> a >> b;
std::cout << big_num_multi(a,b) << std::endl;
return 0;
}
四、关键点解析
-
数组长度:
- 乘法结果的最大长度为
n + m位。 - 使用整型数组保存每一位,最后转字符串返回。
- 乘法结果的最大长度为
-
进位管理:
- 每一位乘法结果大于等于 10 时,需要向高位进位。
- 注意 :每轮外层循环结束后,必须将
jin重置为 0,否则会影响下一轮计算。
-
移位处理:
- 外层循环控制 b 的位数,乘完一轮后结果数组需要对应移位。
idx = max_len - (m - i)计算每轮加法的起始位置。
-
零处理:
- 如果任意输入是
"0",结果直接返回"0",避免多余计算。 - 转字符串时去掉前导零,保证输出美观。
- 如果任意输入是
五、时间与空间复杂度
- 时间复杂度 :
O(n * m),n、m 分别为两个数的长度,每一位都需要乘一次。 - 空间复杂度 :
O(n + m),数组保存乘积每一位的结果。
六、示例
输入:
123 456
输出:
56088
输入:
999 999
输出:
998001
输入:
0 123456
输出:
0
七、总结
- 大整数乘法可以通过模拟手工竖式乘法实现。
- 核心思想是逐位相乘 + 进位管理 + 移位累加。
- 适用于任意长度的非负整数字符串乘法。