问题求解:
给定两个大整数x与y都是2的整数倍,先要计算它们的乘积z。
求解:
大整数我们可以利用数组来存放他们的二进制,然后对半分,利用一个简单的分配律公式。
这样我们就可以把两个很长的二进制不停的对半划分直到只剩一位,一位二进制就非常好求解了,这样就可以利用递归。
二进制存到数组的情况如图:
在求解之前,我们需要几个函数来做一下准备工作。
left()求的是二进制数的左边,right()就是右边。
ten_to_two()将十进制转化为二进制,two_to_ten将二进制转化为十进制。
char_to_int()将输入的二进制字符存到数组内。
show() 用来输出数组。
big_mult()就是主要的递归函数。
完整代码如下
#include<stdio.h>
#include<iostream>
#include<math.h>
using namespace std;
#define max 20
void left(int* a, int* b, int n) {
for (int i = 0; i < max; i++)
b[i] = 0;
for (int i = n/2; i <= n ; i++)
b[i-n/2] = a[i];
}
void right(int* a, int* b, int n) {
for (int i = 0; i < max; i++)
b[i] = 0;
int i;
for (i = 0; i < n/2; i++)
b[i] = a[i];
b[i] = '\0';
}
long two_to_ten(int *a) {
long s = a[0];
long x = 1;
for (int i = 1; i < max; i++) {
x *= 2;
s += a[i] * x;
}
return s;
}
void ten_to_two(int x, int* a) {
int i = 0;
while (x > 0) {
a[i++] = x % 2;
x = x / 2;
}
for (int j = i; j < max; j++)
a[j] = 0;
}
void char_to_int(int* a, char* s, int n) {
for (int i = 0; i < n; i++)
a[i] = int(s[n - 1 - i]-'0');
for (int i = n; i < max; i++)
a[i] = 0;
}
void show(int* a,int n) {
for (int i = n-1; i >= 0; i--)
cout << a[i];
cout << endl;
}
void big_mult(int x[], int y[] ,int z[], int n) {
long e, e1, e2, e3, e4;
int x_left[max], x_right[max], y_left[max], y_right[max];
int xl_yl[max], xl_yr[max], xr_yl[max], xr_yr[max];
for (int i = 0; i < max; i++)
z[i] = 0;
if (n == 1) {
if (x[0] == 1 && y[0] == 1)
z[0] = 1;
else
z[0] = 0;
}
else {
left(x, x_left, n);
right(x, x_right, n);
left(y, y_left, n);
right(y, y_right, n);
big_mult(x_left, y_left, xl_yl, n / 2);
big_mult(x_left, y_right, xl_yr, n / 2);
big_mult(x_right, y_left, xr_yl, n / 2);
big_mult(x_right, y_right, xr_yr, n / 2);
e1 = two_to_ten(xl_yl);
e2= two_to_ten(xl_yr);
e3 = two_to_ten(xr_yl);
e4 = two_to_ten(xr_yr);
e = e1 * (int)pow(2, n) + (e2 + e3) * (int)pow(2, n / 2) + e4;
ten_to_two(e, z);
}
}
int main() {
long e;
char a[] = "10101100";
char b[] = "10010011";
int x[max], y[max], z[max];
int n = 8;
char_to_int(x, a, n);
char_to_int(y, b, n);
cout << "x:" ; show(x, n);
cout << "y:" ; show(y, n);
big_mult(x, y, z, n);
cout << "z:" ; show(z, n);
cout << "对应的二进制:" << endl;
long xt, yt, zt;
xt=two_to_ten(x);
yt=two_to_ten(y);
zt=two_to_ten(z);
cout << "x_ten:" << xt << endl;
cout << "y_ten:" << yt << endl;
cout << "z_ten:" << zt << endl;
return 0;
}