下面这个表是用这个算法计算981 X 1234 = 1210554的实例(蓝色字体标记的是乘数和被乘数,红色背景部分是中间过程,红色字体是结果)。
(这个图用OpenOffice和dia做出来,有点麻烦哦,不知道有没有什么更方便的工具?)
很容易看出规律出来:
1、粉红色格式里头的数为对应列和行位置上数的乘积。如第一行,9=9 X 1,这样就可以求出所有粉红色格子里头的数。 2、把粉红色格子里头的数的不同位分别放在红色斜线的两侧,如果十位没有,那么用零补充。 3、从右下角开始,我们把同处于斜线一侧的数相加,结果存放到对应的左下部位的格子里头。如4=4, 5=2+0+3, 5=6+3+4+0+2 mod 10[进位为一], 0=1[进位]+3+7+2+6+0+1 mod 10,以此类推,直到左上角。
[1] lnmp.c -- count the product of two large numbers' multiplication
/* set ts=4 */
/*
* FILE: lnmp.c
* Funciton: Count the product of two large numbers' multiplication
*/
/*
* Author: Wu Zhangjin, <zhangjinw@gmail.com>
* (c) 2006-12-31 dslab.lzu.edu.cn Lanzhou University
* License GPL Version 2
*
*/
#include<stdio.h>/* standard input/output functions */ #include<string.h>/* needed by strlen function */ #define MAX_DIGIT 2000 /* define the max digit of number here*/
/**
* mulof_ln - count the product of two large numbers' multiplication
* @ln_arr: the address of two large numbers
* @pofm: the address of the result array
*
* Description:
* the function use the algorithm: multiplication using a rectangle
* like this: 981 X 1234 = 1210554
* 9 8 1
* 1 0/9 0/8 0/1 1
* 2 1/8 1/6 0/2 2
* 1 2/7 2/4 0/3 3
* 0 3/6 3/2 0/4 4
* 5 5 4
* you can find the the rule of it easily.
*
* Returns:
* the address of the product of multiplication.
*
*/
char* mulof_ln(char ln_arr[2][MAX_DIGIT],char pofm[2*MAX_DIGIT-1]) { int digit_arr[2], digit_pofm, i, j, k, m, tmp, carry; char td_arr[MAX_DIGIT][MAX_DIGIT][2];
/*count the intermediate result, save them to a three-dimensional array*/ for(i = digit_arr[0]- 1; i >= 0; i --) for(j = digit_arr[1]- 1; j >= 0; j --) {
tmp =(ln_arr[0][i]-'0')*(ln_arr[1][j]-'0');
td_arr[j][i][0]= tmp / 10;
td_arr[j][i][1]= tmp % 10; }
/*count the result, save it to the result array*/ for(m = digit_pofm; m >= 0; m--) {
tmp = carry; for(i = digit_arr[0]- 1; i >= 0; i --) for(j = digit_arr[1]- 1; j >= 0; j --) for(k = 1; k >= 0; k --) if(m == i+j+k) tmp = tmp + td_arr[j][i][k];
carry = tmp / 10;
pofm[m]= tmp%10 +'0'; }
/*take out the ZERO before the result*/
tmp = 0; for(i = 0; i < digit_pofm; i ++){ if(pofm[i]!='0')break; else tmp ++; } for(j = tmp, i = 0; j <= digit_pofm + 1; j ++, i ++)
pofm[i]= pofm[j];
return pofm; }
/**
* main - the main function for testing the function: mulof_ln
*/
int main() { char ln_arr[2][MAX_DIGIT]; char pofm[2*MAX_DIGIT-1];/* the product of the multiplication */
printf("Please input two large numbers: \n"); scanf("%s %s", ln_arr[0], ln_arr[1]);
printf("The product of the muliplication is:\n%s\n", mulof_ln(ln_arr, pofm));
return 0; }
Demo
shell> make lnmp
cc lnmp.c -o lnmp
shell> ./lnmp
Please input two large numbers:
2
5
The product of the muliplication is:
10
shell> ./lnmp
Please input two large numbers:
22222222222222222222222222222222222222222222222222222222222222222222222222
5
The product of the muliplication is:
111111111111111111111111111111111111111111111111111111111111111111111111110
shell> ./lnmp
Please input two large numbers:
0000000000000000000000000000000000000000000000002
000000000000000000000000000000000000000000000055
The product of the muliplication is:
110
[2] rton.c -- count the result of r to the nth(r ^ n)
说明:这里并不是直接调用上面的大数乘积的function,为了更方便地操作和节省内存,进行了一定的调整。
/* set ts=4 */ /*
* FILE: rton.c
* Funciton: count the r to the nth
*
*/
/*
* Author: Wu Zhangjin, <zhangjinw@gmail.com>
* (c) 2006-12-31 dslab.lzu.edu.cn Lanzhou University
* License GPL Version 2
*
*/
#include<stdio.h>/* standard input/output functions */ #include<string.h>/* needed by strlen function */ #define MAX_DIGIT 10 /* define the max digit of number here*/ #define MAX_N 25 /**
* mulof_ln - count the product of two large numbers' multiplication
* @m0: the address of two large numbers
* @m1: the address of two large numbers
* @pofm: the address of the result array
*
* Description:
* the function use the algorithm: multiplication using a rectangle
* like this: 981 X 1234 = 1210554
* 9 8 1
* 1 0/9 0/8 0/1 1
* 2 1/8 1/6 0/2 2
* 1 2/7 2/4 0/3 3
* 0 3/6 3/2 0/4 4
* 5 5 4
* you can find the the rule of it easily.
*
* Returns:
* the address of the product of multiplication.
*
* Notes:
* the index of td_arr must be engough large, when you use it to count the power like R ^ N
*/
char* mulof_ln(char* m0,char* m1,char pofm[2*MAX_DIGIT-1]) { int digit_arr[2], digit_pofm, i, j, k, m, tmp, carry; char td_arr[MAX_DIGIT*MAX_N][MAX_DIGIT*MAX_N][2];
/*count the intermediate result, save them to a three-dimensional array*/ for(i = digit_arr[0]- 1; i >= 0; i --) for(j = digit_arr[1]- 1; j >= 0; j --) {
tmp =(m0[i]-'0')*(m1[j]-'0');
td_arr[j][i][0]= tmp / 10;
td_arr[j][i][1]= tmp % 10; }
/*count the result, save it to the result array*/ for(m = digit_pofm; m >= 0; m--) {
tmp = carry; for(i = digit_arr[0]- 1; i >= 0; i --) for(j = digit_arr[1]- 1; j >= 0; j --) for(k = 1; k >= 0; k --) if(m == i+j+k) tmp = tmp + td_arr[j][i][k];
carry = tmp / 10;
pofm[m]= tmp%10 +'0'; }
/*take out the ZERO before the result*/
tmp = 0; for(i = 0; i < digit_pofm; i ++){ if(pofm[i]!='0')break; else tmp ++; } if(tmp > 0) for(j = tmp, i = 0; j <= digit_pofm + 1; j ++, i ++)
pofm[i]= pofm[j];
return pofm; }
/**
* mypower - count the R to the nth
* @r: the base of the power, it is a float number.
* @n: the exponent of the power
* @p: the address of the result
*
* Descript:
* call the mulof_ln function to count the large float number R to the nth
*/
char* mypower(char* r,int n,char p[MAX_DIGIT*MAX_N]) { int digit_r, digit_p, i, j, pos_point, pos_point_result, tmp;
memset(p, 0, MAX_DIGIT*MAX_N);
digit_r =strlen(r); for(i = 0; i < digit_r; i ++) if(r[i]=='.')break;
pos_point = i;
/*if R is a decimal, change it to an integer firstly*/ if(pos_point != digit_r){
pos_point_result =(digit_r - i - 1)* n; for(i = pos_point; i <= digit_r; i++)
r[i]= r[i+1]; } /*take out the ZERO before*/
tmp = 0; for(i = 0; i < digit_r -1; i ++){ if(r[i]!='0')break; else tmp ++; } if(tmp > 0) for(j = tmp, i = 0; j <= digit_r + 1; j ++, i ++)
r[i]= r[j];