快速乘法(位运算乘法)原理总结
📌 一、问题背景
实现一个乘法:
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 值 | 含义 |
|---|---|---|
| 0 | a | a·2^0 |
| 1 | 2a | a·2^1 |
| 2 | 4a | a·2^2 |
| 3 | 8a | a·2^3 |
📌 七、整体过程本质
👉 整个算法在做三件事:
- 按位遍历 k(二进制)
- 如果当前位是 1 → 加上对应的 a·2^i
- 每轮把 a 翻倍,进入下一权重
📌 八、例子
计算:
3 × 13
二进制:
13 = 1101
过程:
| k | 是否加 | a | ans |
|---|---|---|---|
| 1101 | ✔ | 3 | 3 |
| 110 | ✘ | 6 | 3 |
| 11 | ✔ | 12 | 15 |
| 1 | ✔ | 24 | 39 |
📌 九、本质总结(一句话)
通过二进制拆分 k,用“a 的倍增(×2)”逐步构造出所有 a·2^i,并按需累加
📌 十、关键理解(最重要)
k决定 选哪些项a += a负责 生成这些项
📌 十一、适用场景
- 大数乘法(防止溢出)
- 模运算(如
(a * b) % mod) - 算法竞赛
- 无乘法指令场景
🚀 最终理解
乘法 = 二进制选择 + 倍增构造