首页 > 代码库 > [算法]Karatsuba快速相乘算法

[算法]Karatsuba快速相乘算法

【概述】

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

此算法主要用于两个大数相乘。普通乘法的复杂度是n2而Karatsuba算法的复杂度仅为3nlog3≈3n1.585(log3是以2为底的)

【步骤

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,

故x0 * y0 便可以由加减法得到。


所以:

  x*y = z2 *  102m +  z1 *  10m +   z0

z2 = x1 * y1

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

z0 = x0 * y0

Recursively computer  (x1*y1)

Recursively computer  (x1 + x0) * (y1 + y0)

Recursively computer  (x0 * y0)

【实例讲解】

设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 + z1 * 10 + z0)可得:

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

【伪代码】

procedure karatsuba(num1, num2)
  if (num1 < 10) or (num2 < 10)
    return num1*num2
  /* calculates the size of the numbers */
  m = max(size_base10(num1), size_base10(num2))
  m2 = m/2
  /* split the digit sequences about the middle */
  x0, x1 = split_at(num1, m2)
  y0, y1 = split_at(num2, m2)
  /* 3 calls made to numbers approximately half the size */
  z0 = karatsuba(x0,y0)
  z1 = karatsuba((x0+y1),(x1+y0))
  z2 = karatsuba(x1,y1)
  return (z2*10^(2*m2))+((z1-z2-z0)*10^(m2))+(z0)

【代码】


[算法]Karatsuba快速相乘算法