快速乘法

7 阅读2分钟

快速乘法(位运算乘法)原理总结

📌 一、问题背景

实现一个乘法:

long mul(long a, long k)

但不直接使用 a * k,而是用:

  • 加法
  • 位运算

📌 二、核心思想

k 拆成二进制:

k = b0·2^0 + b1·2^1 + b2·2^2 + ... + bn·2^n
(bi ∈ {0,1})

那么:

a × k
= a × (b0·2^0 + b1·2^1 + ...)
= b0·(a·2^0) + b1·(a·2^1) + ...

👉 本质:
把乘法拆成多个“是否选择”的加法


📌 三、代码实现

long mul(long a, long k) {
    long ans = 0;
    while (k > 0) {
        if ((k & 1) == 1) ans += a;
        k >>= 1;
        a += a;
    }
    return ans;
}

📌 四、关键点拆解

1️⃣ (k & 1)

判断当前二进制最低位:

  • 1 → 需要加当前的 a
  • 0 → 跳过

2️⃣ k >>= 1

右移一位:

处理下一位(二进制从低到高)

3️⃣ a += a(核心)

等价于:

a = a × 2

📌 五、为什么必须 a += a(数学推导)

我们需要构造:

a·2^0, a·2^1, a·2^2, a·2^3 ...

观察规律:

a·2^(i+1) = 2 × (a·2^i)

所以递推关系:

a_{i+1} = 2 × a_i

👉 对应代码:

a += a

📌 六、完整数学对应关系

轮次 i当前 a 值含义
0aa·2^0
12aa·2^1
24aa·2^2
38aa·2^3

📌 七、整体过程本质

👉 整个算法在做三件事:

  1. 按位遍历 k(二进制)
  2. 如果当前位是 1 → 加上对应的 a·2^i
  3. 每轮把 a 翻倍,进入下一权重

📌 八、例子

计算:

3 × 13

二进制:

13 = 1101

过程:

k是否加aans
110133
11063
111215
12439

📌 九、本质总结(一句话)

通过二进制拆分 k,用“a 的倍增(×2)”逐步构造出所有 a·2^i,并按需累加


📌 十、关键理解(最重要)

  • k 决定 选哪些项
  • a += a 负责 生成这些项

📌 十一、适用场景

  • 大数乘法(防止溢出)
  • 模运算(如 (a * b) % mod
  • 算法竞赛
  • 无乘法指令场景

🚀 最终理解

乘法 = 二进制选择 + 倍增构造