高精度乘法
高精度乘法的核心思想是将两个大数的乘法运算拆解为多个小规模运算,并最终将结果合并得到最后的乘积。
我们来做一道题
大整数乘法
代码如下:
#include<iostream>
#include<string>
using namespace std;
// 定义两个字符数组 `s1` 和 `s2`,分别用于存储输入的两个大数。
// 定义三个整型数组 `a`、`b` 和 `c`,分别用于存储大数的逆序数值形式,以及最终的乘积结果。
char s1[2005], s2[1005];
int a[2005], b[2005], c[2005];
int main()
{
int la, lb, lc; // 定义三个变量 `la`、`lb` 和 `lc`,分别表示两个大数的长度及其乘积的长度。
// 输入两个大数,存储到字符数组 `s1` 和 `s2` 中。
cin >> s1 >> s2;
// 计算第一个大数 `s1` 和第二个大数 `s2` 的长度。
la = strlen(s1);
lb = strlen(s2);
// 将两个大数转换为整数数组,并逆序存储。
// a[1] 对应的是 s1 的最低位(最右边的数字),以此类推。
// b[1] 对应的是 s2 的最低位(最右边的数字),以此类推。
for (int i = 0; i < la; i++)
{
a[la - i] = s1[i] - '0'; // 将字符转为整数,并倒序存储
}
for (int i = 0; i < lb; i++)
{
b[lb - i] = s2[i] - '0'; // 同样将 s2 的字符倒序存储为整数
}
// 乘积的最大长度不会超过 la + lb,因此 lc 被初始化为 la + lb。
lc = la + lb;
// 开始进行大数乘法运算。模拟手工计算过程,将每一位的乘积加到对应的位置。
for (int i = 1; i <= la; i++)
{
for (int j = 1; j <= lb; j++)
{
// 计算 a[i] * b[j] 并加到 c[i + j - 1] 位置(模拟手工乘法的进位规则)。
c[i + j - 1] += a[i] * b[j];
// 将当前位置的数值向高位进位,避免溢出,确保个位数字留在当前位。
c[i + j] += c[i + j - 1] / 10;
c[i + j - 1] %= 10; // 取个位数,放在当前位。
}
}
// 如果乘积最高位 lc 是 0,则去掉该位(最高位无意义)。
if (c[lc] == 0 && lc > 0)
{
lc--; // 减少乘积的实际位数。
}
// 从高位开始输出乘积结果。由于存储是倒序的,因此需要从最高位开始输出。
for (int i = lc; i > 0; i--)
{
cout << c[i]; // 输出每一位结果。
}
return 0; // 程序正常结束。
}
高精度除法
我们来做一道题
洛谷P1480
代码如下:
#include<iostream>
#include<cstring> // 确保包含正确的头文件
using namespace std;
char s1[5005]; // 存储输入的字符串形式的大数
long long b, c[5005], x = 0, a[5005], la, lc; // 全局变量定义
int main()
{
// 输入大数和除数
cin >> s1 >> b;
// 计算大数的长度
la = strlen(s1);
// 将字符串形式的大数转换为数组形式的数值(从下标0开始)
for (int i = 0; i < la; i++) {
a[i] = s1[i] - '0'; // 将字符'0'-'9'转换为整数0-9
}
// 开始进行大数除法的模拟
for (int i = 0; i < la; i++) {
// 计算当前位数的商:先加上前面的余数,再除以b得到当前位商
c[i] = (x * 10 + a[i]) / b;
// 计算新的余数:将前面的余数与当前位合并,然后取模b
x = (x * 10 + a[i]) % b;
}
// 找到商的第一个非零位,避免前导零
lc = 0;
while (c[lc] == 0 && lc < la) {
lc++;
}
// 输出结果,如果商从头到尾都为0,则只输出0
if (lc == la) {
cout << 0;
} else {
// 从第一个非零位开始输出商
for (int i = lc; i < la; i++) {
cout << c[i];
}
}
return 0;
}
gitee代码源码