您的位置:首页 >C++快速幂算法实现与优化技巧
发布于2026-04-15 阅读(0)
扫一扫,手机访问
std::pow不适用于整数快速幂,因其转浮点导致精度误差且不支持取模;应手写fast_pow,核心是二进制拆分指数、每次乘法后取模、先对base取模防溢出。

pow 不能直接用于整数快速幂标准库的 std::pow 是为浮点数设计的,输入 int 也会先转成 double,再调用浮点幂函数——这会引入精度误差(比如 pow(10, 9) 可能返回 999999999 或 1000000001),且不支持取模。竞赛、密码学或大数场景下,你真正需要的是「整数底数 + 整数指数 + 模数」的三元组合运算。
long long 调用 std::pow 后强制转回整型——结果不可靠fast_pow 的核心循环怎么写才安全经典二分思想:把指数拆成二进制,每次检查最低位是否为 1,是则累乘当前幂次的底数,然后底数自乘、指数右移。关键在溢出控制和边界处理。
long long 存中间结果,哪怕输入是 int——a * a 容易溢出res = (res * base) % mod,不能等最后再取模exp >>= 1,别用 exp /= 2(虽等价但语义不清,且对负数行为不同)long long fast_pow(long long base, long long exp, long long mod) {
long long res = 1;
base %= mod; // 先取模,防 base >= mod
while (exp > 0) {
if (exp & 1) res = (res * base) % mod;
base = (base * base) % mod;
exp >>= 1;
}
return res;
}模数为 1 时,所有结果都应为 0(除了 0^0 这种特殊情况);但若代码没提前判断,base %= mod 会导致除零错误(因为 % 1 合法,但 % 0 不合法)。更隐蔽的是负模数——C++ 中 a % b 符号取决于被除数,不是数学意义的非负剩余。
if (mod <= 0) throw std::invalid_argument("mod must be positive");% 得到 [0, mod) 区间结果;如需非负余数,用 ((x % mod) + mod) % mod递归写法简洁,但栈深度随指数位数增长(最多约 64 层),一般没问题;真正危险的是忘记处理 exp == 0 的 base case,或递归调用时没对指数做整除导致死循环。
exp / 2 必须用整除(exp >> 1 更安全),否则小数指数会卡住实际用的时候,最常漏掉的是 base %= mod 这一步——尤其当 base 接近 LLONG_MAX 时,第一次 base * base 就溢出,后面全错。这个细节没有警告,也难调试。
上一篇:万年历查安全期的正确方法
下一篇:番茄小说关闭推送通知设置方法
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
售后无忧
立即购买>office旗舰店
正版软件
正版软件
正版软件
正版软件
正版软件
1
2
3
7
9