引入
在上一篇文章中(高精度算法--大数加法-CSDN博客),简单讲解了高精度算法的加法操作
这篇文章将会讲解高精度乘法
原理
高精度乘法的原理与加法有异曲同工之妙,我们直接举一个栗子
99 × 12
对于两个因数,我们分别看作 a 和 b ,积看作 c
因数和积的每个数位从右到左从1开始标号
如图:
那么每一位相乘都可以对应表示为:
根据图示我们可以找到这样的规律:a的下标 + b的下标 - 1 = c的下标
对应相乘之后再对积按数位依次进位即可得到结果
代码实现
创建变量
- 创建两个字符串变量用于输入因数
- 创建三个数组a,b,c 用于模拟竖式计算
- 创建循环变量,以及三个用于保存数组长度的变量
注: 三个整型数组的大小一定要开足
string s1, s2;
int a[100], b[100], c[100] = { 0 };
int i,j,la,lb,lc;
输入因数
- (本例中)使用getline函数输入两个因数
- la,lb分别保存两个因数的长度
- 用两个循环逆序储存两个因数
注:
1.(此例中)数组的下标是从后往前移动,字符串的下标是从前往后移动
2.字符串储存的是字符,所以在储存到数组时要减字符0才能得到对应的数字
3.在上述图例中可以看到a,b,c的下标计算都从1开始,为了方便书写代码,在逆序储存因数时要空出下标为0的元素位置
getline(cin, s1);
getline(cin, s2);
la = s1.size();
lb = s2.size();
for (i = 0; i < la; i++)
{
a[la - i] = s1[i] - '0';
}
for (i = 0; i < lb; i++)
{
b[lb - i] = s2[i] - '0';
}
模拟竖式计算
- 用 la+lb 可以得到积的最大位数 lc
- 用两层循环模拟上述栗子中按数位相乘的过程
注:模拟进位时,进位和保留个位两个步骤顺序不能写反
lc = la + lb;
for (i = 1; i <= la; i++)
{
for (j = 1; j <= lb; j++)
{
c[i + j - 1] += a[i] * b[j];
c[i + j] += c[i + j - 1] / 10;
c[i + j - 1] %= 10;
}
}
调整循环变量lc
与加法相同,积的位数不一定是两因数位数之和,所以需要通过从后往前遍历去寻找积的最高位
因为 c 已经初始化了,所以未更改过的位置一定是0,在遍历的过程中只需要判断是否为0即可
注:因为因数有可能为 0 ,所以循环条件在元素为 0 的同时也要考虑积为 0 的情况,用lc > 0加以限制
while (c[lc] == 0 && lc > 0)
{
lc--;
}
输出得数
因为模拟过程中是逆序操作的,所以在输出时需要逆序输出
for (i = lc; i > 0; i--)
{
cout << c[i];
}
完整代码
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s1, s2;
int a[100], b[100], c[100] = { 0 };
int i,j,la,lb,lc;
getline(cin, s1);
getline(cin, s2);
la = s1.size();
lb = s2.size();
for (i = 0; i < la; i++)
{
a[la - i] = s1[i] - '0';
}
for (i = 0; i < lb; i++)
{
b[lb - i] = s2[i] - '0';
}
lc = la + lb;
for (i = 1; i <= la; i++)
{
for (j = 1; j <= lb; j++)
{
c[i + j - 1] += a[i] * b[j];
c[i + j] += c[i + j - 1] / 10;
c[i + j - 1] %= 10;
}
}
while (c[lc] == 0 && lc > 0)
{
lc--;
}
for (i = lc; i > 0; i--)
{
cout << c[i];
}
return 0;
}
如果文章内容有误,欢迎指正