乘法在计算机语言,karatsuba乘法

本词条缺少信息栏、概述图,补充相关内容使词条更完整,还能快速升级,赶紧来编辑吧!

Karatsuba乘法是一种快速乘法。此算法在1960年由Anatolii Alexeevitch Karatsuba 提出,并于1962年得以发表。[1]

此算法主要用于两个大数相乘。普通乘法的复杂度是n2,而Karatsuba算法的复杂度仅为3n^log3≈3n^1.585(log3是以2为底的)[2]

karatsuba乘法算法描述

编辑

语音

karatsuba乘法步骤简介

Karatsuba算法主要应用于两个大数的相乘,原理是将大数分成两段后变成较小的数位,然后做3次乘法,并附带少量的加法操作和移位操作。

现有两个大数,x,y。

首先将x,y分别拆开成为两部分,可得x1,x0,y1,y0。他们的关系如下:

x = x1 * 10m + x0;

y = y1 * 10m + y0。其中m为正整数,m < n,且x0,y0 小于 10m。

那么 xy = (x1 * 10m + x0)(y1 * 10m + y0)

=z2 * 102m + z1 * 10m + z0,其中:

z2 = x1 * y1;

z1 = x1 * y0 + x0 * y1;

z0 = x0 * y0。

此步骤共需4次乘法,但是由Karatsuba改进以后仅需要3次乘法。因为:

z1 = x1 * y0+ x0 * y1

z1 = (x1 + x0) * (y1 + y0) - x1 * y1 - x0 * y0,

故z1 便可以由一次乘法及加减法得到。

karatsuba乘法实例展示

设x = 12345,y=6789,令m=3。那么有:

12345 = 12 * 1000 + 345;

6789 = 6 * 1000 + 789。

下面计算:

z2 = 12 * 6 = 72;

z0 = 345 * 789 = 272205;

z1 = (12 + 345) * (6 + 789) - z2 - z0 = 11538。

然后我们按照移位公式(xy = z2 * 10^(2m) + z1 * 10^(m) + z0)可得:

xy = 72 * 10002 + 11538 * 1000 + 272205 = 83810205。

karatsuba乘法效率分析

编辑

语音

对于给定的n位大数,算法的复杂度不超过3nlog3≈ 3n1.585。

karatsuba乘法编程实现

编辑

语音

karatsuba乘法c语言:

bigint mult(bigint a, bigint b)

{

bigint c;

c.len = a.len + b.len ;

for(int i=1; i <= c.len; i++) c.s[i] = 0;

for(int i=1; i <= a.len; i++)

for(int j=1; j <= b.len; j++)

c.s[i+j-1] += a.s[i]*b.s[j];

for(int i=1; i<= c.len ; i++)

{ c.s[i+1] += c.s[i]/10; c.s[i] %= 10; }

}

karatsuba乘法python:

在以前的python2中,整型分为int和long,也就是整型和长整型, 长整型不存在溢出问题, 即可以存放任意大小的数值. 在python3 中,统一使用长整型.因此python整数运算不需要考虑数据类型;

其次,在python源码:Objects/longobject.c中有对long整型的实现,其中对于数字的相加,内部就是实现了此Karatsuba算法,实现于k_mul,对源码感兴趣对可以了解

static PyLongObject *

k_mul(PyLongObject *a, PyLongObject *b)

{

Py_ssize_t asize = Py_ABS(Py_SIZE(a));

Py_ssize_t bsize = Py_ABS(Py_SIZE(b));

.....

.....

}

karatsuba乘法伪代码描述

编辑

语音

procedure Karatsuba(num1,num2)

if (num1<10) or (num2<10)

return num1 * num2

/*calculates the size of the numbers*/

m = max(size(num1),size(num2))

m2 = m/2

high1, low1 = split_at(num1, m2)

high2, low2 = split_at(num2, m2)

/*calls made to numbers approximately half the size*/

z0 = karatsuba(low1, low2)

z1 = karatsuba((low1 + high1),(low2 + high2))

z2 = karatsuba(high1,high2)

return(z2 * 10^(m)) + ((z1 - z2 - z0)* 10^(m/2)) + (z0)

参考资料

1.

Karatsuba,Yu. Ofma.Multiplication of Many-Digital Numbers by Automatic Computers:Proceedings of the USSR Academy of Sciences,1962:293-294

2.

Karatsuba.The Complexity of Computations:Proceedings of the Steklov Institute of Mathematics,1995:169-183

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值