VS2022
大数相乘是公钥密码学重要的编程基础知识,本文使用小学生的方法,用数组实现大数相乘。
一、代码如下
#include<iostream>
#define MAXN 20
using namespace std;
void ntom(int a[], int n, int b[], int m) {//将n维数组高位补0成m维数组
for (int i = 0; i < m - n; i++)
b[i] = 0;
for (int i = m - n, j = 0; i < m; i++, j++)
b[i] = a[j];
}
void Mto0(int a[], int s, int t) {//就数组s位到t位初始化为0
for (int i = s; i < t; i++)
a[i] = 0;
}
void add(int a[], int b[], int c[], int n) {//c=a+b
int temp1 = 0, temp2 = 0, e, d;//temp是进位标识,e,d是避免对a,b数组值的修改。
for (int i = n - 1; i >= 0; i--) {
e = a[i]; d = b[i];
if (e && d) {//异或执行
temp2 = 1; c[i] = 0 + temp1;
}
else if (e || d) {
if (temp1) {
temp2 = 1; c[i] = 0;
}
else {
temp2 = 0; c[i] = 1;
}
}
else {
temp2 = 0; c[i] = 0 + temp1;
}
temp1 = temp2; temp2 = 0;//进位标识前进一步。
}
}
void mult(int x1[], int y1[], int z[], int n) {//防止溢出,n代表y的位数,小于MAXN/2。
int x[MAXN], y[MAXN];
ntom(x1, n, x, MAXN);//将x1的高位补0
ntom(y1, n, y, MAXN);//将y1的高位补0
int x2[MAXN]; Mto0(x2, 0, MAXN);
for (int i = MAXN - 1, k = 0; i >= MAXN - n; i--, k++) {//从低位到高位依次移位。
if (y[i] == 1) {
for (int j = MAXN - n; j < MAXN; j++) {
x2[j - k] = x[j];
}
Mto0(x2, i + 1, MAXN);
}
else {
Mto0(x2, 0, MAXN);
}
add(z, x2, z, MAXN);//将移位后的x加到z中。
}
}
void main()
int n = 8;
int x1[] = { 1,0,1,0,1,1,0,0 };
int y1[] = { 1,0,0,1,0,0,1,1 };
disp(x1, n);//打印x
disp(y1, n);//打印y
int z[MAXN]; Mto0(z, 0, MAXN);//将z置0
mult(x1, y1, z, n);
disp(z, MAXN);
}
总结
实现乘法必须实现加法,文章后续会使用递归方法,敬请期待。
这个代码能运行,但显然还有很大的优化空间。