# 卡拉楚巴算法

Karatsuba算法Karatsuba乘法卡拉楚巴乘法卡拉楚巴算法（俄語：Алгоритм Карацубы），是一种快速乘法算法，由1960年提出并于1962年发表。[1][2][3]它将两个${\displaystyle n}$位数字相乘所需的一位数乘法次数减少到了至多${\displaystyle 3n^{\log _{2}3}\approx 3n^{1.585}}$（如果${\displaystyle n}$是2的乘方，则正好为${\displaystyle n^{\log _{2}3}}$）。因此它比要${\displaystyle n^{2}}$次个位数乘法的经典算法要快。例如，对于两个1024位的数相乘（${\displaystyle n=1024=2^{10}}$），卡拉楚巴算法需要${\displaystyle 3^{10}=59049}$次个位数乘法，而经典算法需要${\displaystyle (2^{10})^{2}=1048576}$次。Toom–Cook算法是此算法更快速的泛型。对于充分大的${\displaystyle n(n\gg 1)}$Schönhage-Strassen演算法甚至更快，算法的时间复杂度为${\displaystyle O(n\log n\log \log n)}$

## 算法

### 示例

12345 = 12 · 1000 + 345
6789 = 6 · 1000 + 789

z2 = 12 × 6 = 72
z0 = 345 × 789 = 272205
z1 = (12 + 345) × (6 + 789) − z2z0 = 357 × 795 − 72 − 272205 = 283815 − 72 − 272205 = 11538

## 实现

### 伪代码实现

```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 */
high1, low1 = split_at(num1, m2)
high2, low2 = split_at(num2, m2)
/* 3 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^(2*m2))+((z1-z2-z0)*10^(m2))+(z0)```

### Python代码实现

```# Python 2 and 3
def karatsuba(num1, num2):
num1Str, num2Str = str(num1), str(num2)

if num1Str[0] == '-': return -karatsuba(-num1, num2)
if num2Str[0] == '-': return -karatsuba(num1, -num2)

if num1 < 10 or num2 < 10: return num1 * num2

maxLength = max(len(num1Str), len(num2Str))
num1Str = ''.join(list('0' * maxLength)[:-len(num1Str)] + list(num1Str))
num2Str = ''.join(list('0' * maxLength)[:-len(num2Str)] + list(num2Str))

splitPosition = maxLength // 2
high1, low1 = int(num1Str[:-splitPosition]), int(num1Str[-splitPosition:])
high2, low2 = int(num2Str[:-splitPosition]), int(num2Str[-splitPosition:])
z0, z2 = karatsuba(low1, low2), karatsuba(high1, high2)
z1 = karatsuba((low1 + high1), (low2 + high2))
return z2 * 10 ** (2 * splitPosition) + (z1 - z2 - z0) * 10 ** (splitPosition) + z0
```

## 参考文献

1. ^ A. Karatsuba and Yu. Ofman. Multiplication of Many-Digital Numbers by Automatic Computers. Proceedings of the USSR Academy of Sciences. 1962, 145: 293–294.
2. ^ A. A. Karatsuba. The Complexity of Computations (PDF). Proceedings of the Steklov Institute of Mathematics. 1995, 211: 169–183 [2013-07-25]. （原始内容存档 (PDF)于2020-03-26）.
3. ^ Knuth D.E.（1969）The art of computer programming. v.2. Addison-Wesley Publ.Co., 724 pp.