大数乘法的算法演进:从小学方法到 Karatsuba

在计算机科学中,乘法是最基础的算术运算之一,但大数乘法的效率问题却一直是算法研究的核心课题。从小学课堂上的竖式乘法,到高斯的复数乘法优化,再到能突破时间壁垒的Karatsuba 算法,每一次创新都让大数乘法的效率实现质的提升。本文将结合经典的算法理论,从时间复杂度的角度,梳理大数乘法的算法演进过程,带你理解背后的核心思想。

一、基础铺垫:加法与乘法的时间复杂度

在研究大数乘法前,我们先明确n 位二进制数(十进制同理)算术运算的时间复杂度基准,这是后续分析的基础。

1.1 小学加法:线性时间且最优

小学阶段的竖式加法,逐位相加并处理进位,其时间复杂度为Θ(n) ,这是线性时间 。更重要的是,加法算法的下界是 Ω(n) ,即小学加法是最优算法 ,无法被优化到亚线性时间。证明核心:任何加法算法必须读取所有输入位。若存在未检查的位,翻转该位后算法会输出错误结果,因此加法的时间复杂度无法突破线性。

1.2 小学乘法:平方时间的瓶颈

小学竖式乘法的思路是:用一个数的每一位去乘另一个数的每一位,得到中间结果后逐位错位相加。对于两个 n 位数字,需要进行n×n 次位乘法 ,再加上错位相加的线性操作,整体时间复杂度为Θ(n²) ,这是二次时间

二次时间的问题在于,当 n(数字的位数)足够大时,运算量会呈平方级爆炸式增长。比如 1000 位的大数相乘,小学方法需要约 100 万次运算,而 10000 位的大数相乘则需要 1 亿次运算,效率极低。

自然会产生两个问题:

  1. 大数乘法能否做到线性时间?(目前学术界尚无答案)
  2. 能否突破 Θ(n²) 的二次时间壁垒?(答案是肯定的,这就是后续要讲的核心)

二、高斯的经典优化:少一次乘法,省25%工作量

在进入大数乘法的分治优化前,先看高斯在复数乘法中提出的经典技巧,这是后续 Karatsuba 算法的核心灵感来源。

2.1 复数乘法的原始计算

两个复数 a+bi 和 c+di 相乘的结果为:(a+bi)(c+di)=(ac−bd)+(ad+bc)i要得到结果的实部和虚部,原始方法需要 4 次实数乘法(ac、bd、ad、bc)+ 少量加减法。若乘法成本为1,加法为1,原始成本为4.02。

2.2 高斯的3次乘法优化

高斯通过变形,将乘法次数从 4 次减少到 3 次,仅需3.05即可完成计算,节省 25% 的工作量:

  1. 计算 X1=(a+b)×c
  2. 计算 X2=a×(c+d)
  3. 计算 X3=b×d
  4. 实部:ac−bd=X2−X3−(X1−ac−X3)=X2−X1
  5. 虚部:ad+bc=X1−X3

核心思想用加减法的低代价,换取乘法的高代价减少,这是所有乘法优化算法的核心思路。

三、简单分治乘法的失败

既然直接的竖式乘法是 Θ(n²),我们尝试用分治思想拆解问题:将大数拆分为小数,递归求解后合并结果。

3.1 大数的分治拆解

对于两个 n 位大数 X 和 Y,将其各拆分为高 n/2 位和低 n/2 位:X=a×2n/2+b,Y=c×2n/2+d其中 a、b、c、d 均为 n/2 位数字,二者的乘积可展开为:X×Y=ac×2n+(ad+bc)×2n/2+bd

3.2 分治乘法的递归实现

基于上述展开式,分治乘法的递归算法(MULT)如下:

复制代码
MULT(X, Y):
    若X和Y均为1位数字,直接返回X×Y
    否则将X拆分为a(高n/2位)、b(低n/2位),Y拆分为c(高n/2位)、d(低n/2位)
    返回 MULT(a,c)×2^n + (MULT(a,d) + MULT(b,c))×2^{n/2} + MULT(b,d)

3.3 简单分治乘法仍为Θ(n²)

为该算法建立递推关系(忽略常数,简化为 T (1)=1):T(n)=4×T(n/2)+n其中:

  • 4×T (n/2):递归调用 4 次 n/2 位的乘法(ac、ad、bc、bd)
  • n:拆分和合并的线性时间(移位、加法)

递推求解 :用树状展开法分析,每一层的运算量为4i×n/2i=2i×n,总层数为log2​n,总运算量为:T(n)=n×(1+2+4+...+n)=2n2−n=Θ(n2)

结论:分治只是改变了计算形式,并未减少乘法次数,因此时间复杂度仍为二次。

四、Karatsuba算法突破平方壁垒

1962年,Anatolii Alexeevich Karatsuba 将高斯的3次乘法优化分治思想 结合,提出了Karatsuba 算法,首次突破了Θ(n²) 的二次时间壁垒,这是大数乘法算法的里程碑。

4.1 将4次递归减为3次

Karatsuba 发现,分治乘法中最耗时的是4次递归乘法 ,而其中的ad+bc可以通过高斯技巧变形,仅用3次递归乘法实现:已知 X×Y=ac×2n+(ad+bc)×2n/2+bd,令:

  • e=ac=MULT(a,c)(第 1 次递归)
  • f=bd=MULT(b,d)(第 2 次递归)
  • g=(a+b)×(c+d)=MULT(a+b,c+d)(第 3 次递归)

则中间项 ad+bc=g−e−f,因此乘积可重写为:X×Y=e×2n+(g−e−f)×2n/2+f

4.2 递归实现

复制代码
Karatsuba(X, Y):
    若X和Y均为1位数字,直接返回X×Y
    否则将X拆分为a(高n/2位)、b(低n/2位),Y拆分为c(高n/2位)、d(低n/2位)
    e = Karatsuba(a, c)
    f = Karatsuba(b, d)
    g = Karatsuba(a+b, c+d)
    中间项 = g - e - f
    返回 e×2^n + 中间项×2^{n/2} + f

4.3 时间复杂度提升至Θ(n^log₂3) ≈ Θ(n^1.58)

为 Karatsuba 算法建立递推关系(T (1)=1):T(n)=3×T(n/2)+n其中:

  • 3×T (n/2):仅 3 次递归乘法(e、f、g)
  • n:拆分、加法、减法、移位的线性时间

递推求解:同样用树状展开法,每一层的运算量为3i×n/2i=n×(3/2)i,总层数为log2​n,总运算量为:T(n)=n×[1+3/2+(3/2)2+...+(3/2)log2​n]=3nlog2​3−2n=Θ(nlog2​3)

log2​3≈1.58,因此 Karatsuba 算法的时间复杂度为Θ(n^1.58) ,这是超线性、亚二次的时间复杂度,当 n 足够大时,效率远高于小学乘法的 Θ(n²)。

比如 10000 位大数相乘:

  • 小学方法:约 10^8 次运算
  • Karatsuba 算法:约 10^(1.58×4) = 10^6.32 ≈ 208 万次运算,效率提升近 50 倍。

五、大数乘法的算法演进与后续发展

大数乘法的时间复杂度不断被优化,其演进路径如下:

  1. 幼儿园方法:Θ(n²)(最朴素的逐位相乘)
  2. 小学竖式乘法:Θ(n²)(标准化的逐位相乘 + 错位相加)
  3. 初版分治乘法:Θ(n²)(形式创新,无本质优化)
  4. Karatsuba 算法:Θ(n^1.58)(首次突破二次壁垒,工程中最常用)
  5. 目前已知最快算法:Θ(n logn loglogn)(理论上的极致,实现复杂度极高)

核心规律 :所有高效的大数乘法算法,都遵循用低代价的加减法 / 移位,换取高代价的乘法次数减少的思路,而分治思想则是实现这一思路的核心框架。

六、总结

本文从基础的时间复杂度出发,梳理了大数乘法从小学方法到 Karatsuba 算法的核心演进,核心知识点可总结为:

  1. 小学加法是Θ(n)的最优算法,无法突破线性下界;
  2. 小学乘法的Θ(n²)是二次时间壁垒,初版分治无法突破;
  3. 高斯的复数乘法优化是关键灵感:3 次乘法替代 4 次乘法,用加减法换乘法;
  4. Karatsuba算法将高斯优化与分治结合,实现 Θ(n^1.58) 的亚二次时间,是工程中最实用的高效大数乘法算法;
  5. 大数乘法的优化核心:减少高代价的乘法次数,用低代价的加减法 / 移位弥补

Karatsuba算法不仅解决了大数乘法的效率问题,更体现了计算机科学的核心思想:问题的拆解与转化------ 将复杂的大数问题拆分为简单的小数问题,通过局部优化实现全局的效率提升。这一思想也适用于排序、查找、图论等各类算法问题,是每一个程序员都需要掌握的核心思维。


:Karatsuba 算法的适用场景

  • 适合大位数的整数相乘(如密码学中的大素数相乘、大数据中的高精度计算);
  • 对于小位数数字,小学乘法的常数更小,实际运行速度更快(Karatsuba 的递归和加减法会带来额外开销)。

本文基于 CMU 15-251《Great Theoretical Ideas in Computer Science》课程 Lecture23 内容整理。

相关推荐
2401_844221322 小时前
内存对齐与缓存友好设计
开发语言·c++·算法
橘颂TA2 小时前
【笔试】算法的暴力美学——牛客 NC221681:dd爱框框
算法
天天进步20152 小时前
WrenAI 深度解析:算法视角:wren-ai-service 如何利用 RAG 与 Metadata 提升 SQL 准确率?
人工智能·sql·算法
一叶落4382 小时前
36. 有效的数独(Valid Sudoku)题解(C语言)
c语言·数据结构·算法·leetcode·哈希算法
qiuyunoqy2 小时前
Linux进程 --- 5(进程地址空间初识)
linux·c++·算法
Sakinol#2 小时前
Leetcode Hot 100 ——贪心算法
算法·leetcode·贪心算法
AC__dream2 小时前
2024年秋招-美团-技术岗-第一批笔试
数据结构·算法
计算机安禾2 小时前
【C语言程序设计】第28篇:指针的概念与指针变量
c语言·开发语言·数据结构·c++·算法·visual studio code·visual studio
lxh01132 小时前
串联所有单词的子串
算法