大整数乘法

来源:互联网 发布:淘宝ar扫描怎么用 编辑:程序博客网 时间:2024/04/29 08:07

整数乘法问题: 设A和B为两个N位的整数,计算它们的乘积A · B。

要执行一位乘法多少次? N^2次


分治法思想

令N为偶数,则A和B可表示为
其中a1和a2分别为A的前半部和后半部。


bl 和b2则分别为B的前半部和后半部。如果按下述方法得到积(多项式相乘)
 

估算时间效率是多少(即需要多少次一位乘法)?
则要4次N/2位乘法,即N2次一位乘法。因此这种方法没有改进原来的方法。


此时需要乘法多少次?
    这种方法需要3次n/2位的乘法及一些加减法。
    记C(n)为计算两个n位整数相乘所需的基本操作执行次数,则有
         C(n)=3C(n/2)+k·n 
         C(1)=1    
其中,k为常数,KN表示加法、减法所需时间与N成正比。
    解此递归方程,得


其原理在于乘法操作所需时间比加法多得多,因此减少乘法次数,
虽然代价为增加加法运算,总的效果还是加速了运算.
大整数(500比特或1024比特)的乘法用于加密和认证.


网上一道题,若两个大整数位数不同,如何求解?(来自http://www.acmerblog.com/c语言程序设计-大整数乘法数组应用-1220.html)

【问题描述】求两个不超过200位的非负整数的积。

【输入形式】有两行,每行是一个不超过200位的非负整数,没有多余的前导。

【输出形式】一行,即相乘后的结果。结果不能有多余的前导0,即如果结果是342,那么就不能输出为0342。

【样例输入】12345678900

                     98765432100

【样例输出】1219326311126352690000

【样例说明】这两个大整数相乘所得的结果是1219326311126352690000。

01#include <stdio.h>
02char strnum1[210], strnum2[210];
03int num1[210], num2[210], ans[40000];
04int main(){
05    gets(strnum1);
06    gets(strnum2);
07    int m = 0, n = 0;
08 
09    //将字符串转化为数字
10    while (strnum1[m]){
11        num1[m] = strnum1[m] - '0';
12        m++;
13    }
14    while (strnum2[n]){
15        num2[n] = strnum2[n] - '0';
16        n++;
17    }
18    int up; //进位
19    int tmp ; //临时变量
20    int k, p, i, j; // k,p 记录计算的位置
21    for (i = m - 1, k = 0; i >= 0; i--, k++){
22        tmp = 0, up = 0;
23        for (j = n - 1, p = 0; j >= 0; j--, p++){
24            tmp = num1[i] * num2[j] + up + ans[k + p];
25            ans[k + p] = tmp % 10;
26            up = tmp / 10;
27        }
28        if (up > 0)
29            ans[k + p] = up;
30    }
31    int len = m * n;
32    while (ans[len--] == 0);
33    //逆序输出
34    for (int i = len + 1; i >= 0; i--)
35        printf("%d", ans[i]);
36    return 0;
37}

0 0