高精度乘法

引入

在上一篇文章中(高精度加法),简单讲解了高精度算法的加法操作

这篇文章将会讲解高精度乘法

原理

高精度乘法的原理与加法有异曲同工之妙,我们直接举一个栗子

99 × 12

img

对于两个因数,我们分别看作 a 和 b ,积看作 c

因数和积的每个数位从右到左从1开始标号

如图:

img

那么每一位相乘都可以对应表示为:

img

根据图示我们可以找到这样的规律:a的下标 + b的下标 - 1 = c的下标

对应相乘之后再对积按数位依次进位即可得到结果

代码实现

创建变量

  1. 创建两个字符串变量用于输入因数
  2. 创建三个数组a,b,c 用于模拟竖式计算
  3. 创建循环变量,以及三个用于保存数组长度的变量

注: 三个整型数组的大小一定要开足

1
2
3
string s1, s2;
int a[100], b[100], c[100] = { 0 };
int i,j,la,lb,lc;

输入因数

  1. (本例中)使用getline函数输入两个因数
  2. la,lb分别保存两个因数的长度
  3. 用两个循环逆序储存两个因数
  1. (此例中)数组的下标是从后往前移动,字符串的下标是从前往后移动
  2. 字符串储存的是字符,所以在储存到数组时要减字符0才能得到对应的数字
  3. 在上述图例中可以看到a,b,c的下标计算都从1开始,为了方便书写代码,在逆序储存因数时要空出下标为0的元素位置
1
2
3
4
5
6
7
8
9
10
11
12
13
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';
}

模拟竖式计算

  1. 用 la+lb 可以得到积的最大位数 lc
  2. 用两层循环模拟上述栗子中按数位相乘的过程

注:模拟进位时,进位和保留个位两个步骤顺序不能写反

1
2
3
4
5
6
7
8
9
10
11
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加以限制****

1
2
3
4
while (c[lc] == 0 && lc > 0)
{
lc--;
}

输出得数

因为模拟过程中是逆序操作的,所以在输出时需要逆序输出

1
2
3
4
for (i = lc; i > 0; i--)
{
cout << c[i];
}

完整代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#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;
}
如果文章内容有误,欢迎指出