Comba 乘法以(在密码学方面)不太出名的 Paul G. Comba 得名。上面的笔算乘法,虽然比较简单, 但是有个很大的问题:在 O(n^2) 的复杂度上进行计算和向上传递进位,看看前面的那个竖式,每计算一次单精度乘法都要计算和传递进位,这样的话就使得嵌套循环的顺序性很强,难以并行展开和实现。Comba 乘法则无需进行嵌套进位来计算乘法,所以虽然其时间复杂度和基线乘法一样,但是速度会快很多。还是以计算 123 * 456 为例:

1            2            3

x        4             5            6

-----------------------------------------------

6           12          18

5          10         15

4           8          12

------------------------------------------------

4          13          28         27         18

4          13          28         28           8

4          13          30          8

4          16           0

5          6

0         5

------------------------------------------------------

5           6             0            8             8

和普通的笔算乘法很类似,只是每一次单精度乘法只是单纯计算乘法,不计算进位,进位留到每一列累加后进行。所以原来需要 n * n 次进位,现在最多只需要 2n 次即可。

以上就是 Comba 乘法的原理,不过这里有个比较严重的问题:如何保证累加后结果不溢出。上面的例子,假设单精度数 1  位数,双精度是两位数,那万一累加后的结果超过两位数则么办?那没办法,只能用三精度变量了。在大整数算法中,单精度能表示的最大整数是 2^n - 1(n 是单精度变量的比特数),用三个单精度变量 c2,c1,c0 连在一起作为一个三精度变量(高位在左,低位在右),则 c2 || c1 || c0 能表示的最大整数是 2^(3n) - 1,最多能存放 (2^(3n) - 1) / ((2^n - 1)^2) 个单精度乘积结果。当 n = 32 时,能够存放 4294967298 个单精度乘积结果;当 n = 64 时,能够存放约 1.845 * 10^19 个单精度乘积结果,而我一开始规定 bignum 不能超过 25600 个数位,这样使用三精度变量就可以保证累加结果不会溢出了。

有了上面的铺垫,下面就把 Comba 乘法的思路列出来:

1.先将俩个字符数组从后面开始转换为整数数组;

2.乘以后的数组就是c[i+j]+=a[i]*b[j];

3.c数组从小到大依次进位

4.输出,注意c数组是的0是个位,所以从最后一位开始输出,用ok标志不为0的时候开始输出

 #include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
using namespace std;
int main()
{
char a[],b[];
cin>>a>>b;
int x[],y[],c[];
int flag=;
for(int i=;i<;i++)
c[i]=;
for(int i=strlen(a)-;i>=;i--)
x[flag++]=a[i]-'';
int key=;
for(int i=strlen(b)-;i>=;i--)
y[key++]=b[i]-'';
for(int i=;i<flag;i++)
for(int j=;j<key;j++)
c[i+j]+=x[i]*y[j]; for(int i=;i<;i++)
{
if(c[i]>=)
{
c[i+]+=c[i]/;
c[i]%=; }
}
int ok=;
for(int i=-;i>=;i--)
{
if(ok) cout<<c[i];
else if(c[i])
{
cout<<c[i];
ok=; } } return ; }

大整数乘法(Comba 乘法 (Comba  Multiplication)原理)的更多相关文章

  1. 大整数算法[09] Comba乘法(原理)

    ★ 引子          原本打算一篇文章讲完,后来发现篇幅会很大,所以拆成两部分,先讲原理,再讲实现.实现的话相对复杂,要用到内联汇编,要考虑不同平台等等. 在大整数计算中,乘法是非常重要的,因为 ...

  2. 大整数算法[10] Comba乘法(实现)

    ★ 引子 上一篇文章讲了 Comba 乘法的原理,这次来讲讲如何实现.为了方便移植和充分发挥不同平台下的性能,暂时用了三种不同的实现方式: 1.单双精度变量都有的情况. 2.只有单精度变量的情况. 3 ...

  3. 大整数算法[11] Karatsuba乘法

    ★ 引子         前面两篇介绍了 Comba 乘法,最后提到当输入的规模很大时,所需的计算时间会急剧增长,因为 Comba 乘法的时间复杂度仍然是 O(n^2).想要打破乘法中 O(n^2) ...

  4. [转]大整数算法[11] Karatsuba乘法

    ★ 引子         前面两篇介绍了 Comba 乘法,最后提到当输入的规模很大时,所需的计算时间会急剧增长,因为 Comba 乘法的时间复杂度仍然是 O(n^2).想要打破乘法中 O(n^2) ...

  5. 基于Java的大整数运算的实现(加法,减法,乘法)学习笔记

    大整数,顾名思义就是特别大的整数. 一台64位的机器最大能表示的数字是2的64次方减一: 18446744073709551615 java语言中所能表示的整数(int)最小为-2147483648 ...

  6. poj2389-Bull Math(大整数乘法)

    一,题意: 大整数乘法模板题二,思路: 1,模拟乘法(注意"逢十进一") 2,倒序输出(注意首位0不输出) 三,步骤: 如:555 x 35 = 19425  5 5 5  5 5 ...

  7. POJ 1001 解题报告 高精度大整数乘法模版

    题目是POJ1001 Exponentiation  虽然是小数的幂 最终还是转化为大整数的乘法 这道题要考虑的边界情况比较多 做这道题的时候,我分析了 网上的两个解题报告,发现都有错误,说明OJ对于 ...

  8. OpenJudge 2980 大整数乘法

    链接地址:http://bailian.openjudge.cn/practice/2980/ 题目: 总时间限制: 1000ms 内存限制: 65536kB 描述 求两个不超过200位的非负整数的积 ...

  9. 大整数乘法python3实现

    因为python具有无限精度的int类型,所以用python实现大整数乘法是没意义的,可是思想是一样的.利用的规律是:第一个数的第i位和第二个数大第j位相乘,一定累加到结果的第i+j位上,这里是从0位 ...

随机推荐

  1. HibernateQL

    查询语言---QL(Query Language)   NativeSQL-------功能最强大 HQL--Hibernate QL EJB QL (JP QL)---HQL的一个子集 QBC--- ...

  2. 【CodeChef】Small factorials(BigInteger笔记)

    You are asked to calculate factorials of some small positive integers. Input An integer t, 1<=t&l ...

  3. node做验证码

    使用了ccap插件 1.安装: 通用方法:npm install ccap 2. cnst ccap= require('ccap')({ width: 128, height: 40, offset ...

  4. blast+学习之search tools

    search tools:blastn, blastp, blastx, tblastx, tblastn, psiblast, rpsblast, and rpstblastn 1.blastn: ...

  5. mongodb中的__v字段

    "__v"是"versionKey"的简写,当每一个文档由mongoose创建时就会自动添加,代表这该文档的版本,此属性可配置修改,默认为"__v&q ...

  6. 2017最全的php面试题目及答案总结

    最近在网上看到很多的小伙伴们都在询问如何应对php面试,这个对于有工作经验和实战项目的小伙伴来说是没什么问题的,但是对于刚刚学习完php的小伙伴们.php面试却是一个很重要的一步,那么今天php中文网 ...

  7. 基于matlab的边缘提取方法的比较

    1.Matlab简述 Matlab是国际上最流行的科学与工程计算的软件工具,它起源于矩阵运算,已经发展成一种高度集成的计算机语言.有人称它为“第四代”计算机语言,它提供了强大的科学运算.灵活的程序设计 ...

  8. Linux 多线程编程实例

    一.多线程 VS 多进程 和进程相比,线程有很多优势.在Linux系统下,启动一个新的进程必须分配给它独立的地址空间,建立众多的数据表来维护代码段和数据.而运行于一个进程中的多个线程,他们之间使用相同 ...

  9. Struts2全局异常处理

    1.在struts.xml中配置全局异常处理 在Action中抛出异常,此异常可以是action自己抛的,也可以是Service抛出来的,都会跳转到全局异常中,只有在当前Action中配置域全局异常返 ...

  10. tp3.2关联模型 BELONGS_TO

    <?php namespace Home\Model; use Think\Model\RelationModel; class AttenModel extends RelationModel ...