洋紅色箭頭表示乘法，琥珀色表示加法，銀色表示減法，淺青色表示左移。A、B、C顯示了用於獲得中間值的遞歸。
Анато́лий Алексе́евич Карацу́ба
Анато́лий Алексе́евич Карацу́ба
**Karatsuba算法**、**Karatsuba乘法**、**卡拉楚巴乘法**、**卡拉楚巴算法**（俄語：），是一种快速乘法算法，由1960年阿納托利·阿列克謝耶維奇·卡拉楚巴（英语：）提出并于1962年发表。它将两个n位数字相乘所需的一位数乘法次数减少到了至多3n^{{\log \_{2}3}}\approx 3n^{{1.585}}（如果n是2的乘方，则正好为n^{{\log \_{2}3}}）。因此它比要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演算法甚至更快，算法的时间复杂度为O(n\log n\log \log n)。

值得一提的是，卡拉楚巴算法是第一个比小学二次乘法算法渐进快速的算法。

算法
--

### 基本步骤

卡拉楚巴算法主要是用于两个大数的乘法，极大提高了运算效率，相较于普通乘法降低了复杂度，并在其中运用了递归的思想。基本的原理和做法是将位数很多的两个大数x和y分成位数较少的数，每个数都是原来x和y位数的一半。这样处理之后，简化为做三次乘法，并附带少量的加法操作和移位操作。

### 示例

要計算12345和6789的乘積：

12345 = 12 · *1000* + 345
6789 = 6 · *1000* + 789
對只有三個數進行運算的乘法結果：

*z*2 = 12 × 6 = 72
*z*0 = 345 × 789 = 272205
*z*1 = (12 + 345) × (6 + 789) − *z*2 − *z*0 = 357 × 795 − 72 − 272205 = 283815 − 72 − 272205 = 11538
將三部分結果相加並相應地移位：

結果 = *z*2 · (*B**m*)*2* + *z*1 · (*B**m*)*1* + *z*0 · (*B**m*)*0*, i.e.
結果 = 72 · *1000*2 + 11538 · *1000* + 272205 = 83810205.
注意：中間第三次乘法運算的輸入域小於前兩次乘法的兩倍，其輸出域小於前兩次乘法的四倍，並且基數為1000的進位是根據前兩次乘法計算的，在計算這兩個減法時必須考慮。

实现
--

### 伪代码实现

```
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.. Proceedings of the USSR Academy of Sciences. 1962, **145**: 293–294.
2. ↑  A. A. Karatsuba.  (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.

* Karatsuba's Algorithm for Polynomial Multiplication（页面存档备份，存于）
* 埃里克·韦斯坦因.. MathWorld.
* Bernstein, D. J. "Multidigit multiplication for mathematicians（页面存档备份，存于）". Covers Karatsuba and many other multiplication algorithms.

外部鏈接
----

* 卡拉楚巴多項式乘法算法 （页面存档备份，存于）
* 埃里克·韦斯坦因.. MathWorld.
* Bernstein, D. J. "Multidigit multiplication for mathematicians （页面存档备份，存于）". Covers Karatsuba and many other multiplication algorithms.

|  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |  |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 

| * 
* 论
* 编
数论算法 |
| --- |
|  |
| 素数测试 | 
* AKS
* APR（英语：）
* Baillie–PSW（英语：）
* 椭圆曲线（英语：）
* Pocklington（英语：）
* 费马
* 卢卡斯（英语：）
* *卢卡斯-莱默*
* *Lucas–Lehmer–Riesel（英语：）*
* *普罗斯*
* *Pépin（英语：）*
* 二次Frobenius（英语：）
* Solovay–Strassen（英语：）
* 米勒-拉宾

 |
|  |
| 質數生成（英语：） | 
* 阿特金筛法（英语：）
* 埃拉托斯特尼筛法
* Pritchard筛法（英语：）
* Sundaram筛法（英语：）
* 輪式因數分解法（英语：）

 |
|  |
| 整数分解 | 
* 連分數分解 (CFRAC)（英语：）
* Dixon's（英语：）
* Lenstra橢圓曲線 (ECM)（英语：）
* 欧拉因式分解法（英语：）
* 波拉德ρ算法（英语：）
* *p* − 1（英语：）
* *p* + 1（英语：）
* 二次篩選法
* 普通数域筛选法
* *特殊數域篩選法 (SNFS)（英语：）*
* 有理筛选法
* 费马因式分解法（英语：）
* Shanks二次形式（英语：）
* 试除法
* 秀爾演算法

 |
|  |
| 乘法算法 | 
* 古埃及乘算（英语：）
* 長乘法
* 卡拉楚巴算法
* 图姆-库克算法
* 頌哈吉-施特拉森演算法
* 富尔算法（英语：）

 |
|  |
| 歐幾里德除法除法算法 | 
* 二進制（英语：）
* 倍塊法（英语：）
* Fourier（英语：）
* Goldschmidt（英语：）
* Newton-Raphson（英语：）
* 長除法
* 短除法
* SRT

 |
|  |
| 离散对数 | 
* 大步小步算法
* 波拉德ρ算法
* Pollard kangaroo（英语：）
* Pohlig–Hellman（英语：）
* Index calculus（英语：）
* Function field sieve（英语：）

 |
|  |
| 最大公因數 | 
* 二进制最大公因数算法（英语：）
* 輾轉相除法
* 扩展欧几里得算法
* Lehmer's（英语：）

 |
|  |
| 二次剩余 | 
* Cipolla（英语：）
* Pocklington's（英语：）
* Tonelli–Shanks（英语：）
* Berlekamp（英语：）
* Kunerth（英语：）

 |
|  |
| 其他算法 | 
* Chakravala（英语：）
* Cornacchia（英语：）
* 整數關係（英语：）（LLL（英语：）；KZ（英语：））
* 平方求冪
* 整数平方根
* 模幂运算
* 蒙哥马利算法
* Schoof（英语：）
* 特拉亨伯格系統（英语：）

 |
|  |
| 
* *斜体*表示该算法只适用于特殊形式的数字

 |

 |