快速乘经常被用于两数相乘取模的场景,如果两数相乘已经超过数据范围,但取模后不会超过,我们就可以利用这个方法来拆位取模计算贡献,保证每次运算都在数据范围内。当我们使用 int类型做快速乘运算时就相当于模2^32(假设 int类型是 4位)
下面我们先来看我们的普通竖式乘法:
12*31=12*1*10^0+12*3*10^1
那么我们现在把31换成二进制011111
12*(011111)(2进制)=12*1*2^0+12*1*2^1+12*1*2^2+12*1*2^3+12*1*2^4+12*0*2^5
是不是就变成这样了?那么接下来我们考虑 A 和 B 两数相乘的时候我们如何利用加法和位运算来模拟,其实就是将 B 二进制展开,如果 B 的二进制表示下第i位为 1,那么这一位对最后结果的贡献就是 A*(1<<i),即 A<<i。我们遍历 B 二进制展开下的每一位,将所有贡献累加起来就是最后的答案。
代码实现:
int quickMulti(int A, int B) {
int ans = 0;
for ( ; B; B >>= 1) {
if (B & 1) {
ans += A;
}
A <<= 1;
}
return ans;
}