【入门级-算法-5、数值处理算法:高精度的乘法】

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;
}

}

相关推荐
earthzhang20212 小时前
【1039】判断数正负
开发语言·数据结构·c++·算法·青少年编程
谈笑也风生2 小时前
只出现一次的数字 II(一)
数据结构·算法·leetcode
蕓晨2 小时前
auto 自动类型推导以及注意事项
开发语言·c++·算法
mjhcsp3 小时前
C++ 递推与递归:两种算法思想的深度解析与实战
开发语言·c++·算法
_OP_CHEN3 小时前
算法基础篇:(三)基础算法之枚举:暴力美学的艺术,从穷举到高效优化
c++·算法·枚举·算法竞赛·acm竞赛·二进制枚举·普通枚举
m0_748248023 小时前
《详解 C++ Date 类的设计与实现:从运算符重载到功能测试》
java·开发语言·c++·算法
天选之女wow3 小时前
【代码随想录算法训练营——Day61】图论——97.小明逛公园、127.骑士的攻击
算法·图论
im_AMBER3 小时前
Leetcode 47
数据结构·c++·笔记·学习·算法·leetcode
kyle~3 小时前
算法数学---差分数组(Difference Array)
java·开发语言·算法