std::pow不适合整数快速幂,因其为浮点设计、精度丢失且效率低;应手写迭代快速幂,利用二进制拆分与位运算,注意取模防溢出。
为什么 pow 不适合整数快速幂
std::pow 是为浮点数设计的,内部走的是数学库近似计算路径,对整数输入不仅慢,还可能因精度丢失导致结果错误(比如 pow(10, 9) 返回 999999999 或 1000000001)。整数幂运算应手写迭代或递归的快速幂,核心是利用二进制拆分指数。
用位运算实现迭代快速幂(推荐)
迭代写法无递归开销、不易栈溢出,且位操作直观:每次检查 exp 的最低位是否为 1,是则累乘当前的 base;然后 base = base * base,exp >>= 1。注意处理负指数需额外逻辑,但整数幂通常默认非负。
示例(模 M 场景常见,防溢出):
long long fast_pow(long long base, long long exp, long long M) {
long long res = 1;
base %= M;
while (exp > 0) {
if (exp & 1) res = (res * base) % M;
base = (base * base) % M;
exp >>= 1;
}
return res;
}
- 必须对
base先取模,否则第一次base * base就可能溢出 -
exp & 1比exp % 2 == 1更快,也更符合位运算意图 - 若不需要取模,去掉所有
% M,但务必确认base和结果不会溢出long long
什么时候不能直接用位运算快速幂
快速幂假设运算是结合律成立的(如乘法、矩阵乘、模乘),但不适用于所有“幂”语义场景: