c++中如何实现快速幂算法_c++高效计算大功率幂运算

快速幂是整数幂运算的高效算法,时间复杂度O(log n),通过二进制拆分指数和结合律实现,支持取模防溢出,优于std::pow对大整数的精度与模运算缺陷。

c++中如何实现快速幂算法_c++高效计算大功率幂运算

什么是快速幂,为什么不用 pow 函数

标准库std::pow 是为浮点数设计的,对整数大幂(比如 2^1000000)既不保证精度,也不处理模运算,还可能因内部使用 double 导致溢出或舍入错误。快速幂是整数幂运算的替代方案,时间复杂度从 O(n) 降到 O(log n),核心是利用二进制拆分指数和幂的结合律:a^b = (a^(b/2))^2 * (a if b is odd)

手写递归版快速幂(带取模)

适合理解原理,但要注意深度和编译器尾递归优化不可靠。以下实现支持任意非负整数指数和可选模数:

long long quick_pow(long long base, long long exp, long long mod = 1) {
    if (exp == 0) return 1 % mod;
    long long half = quick_pow(base, exp >> 1, mod);
    long long res = half * half % mod;
    if (exp & 1) res = res * base % mod;
    return res;
}
  • mod = 1 表示不取模(此时 % mod 实际为 % 1,恒为 0,需改写逻辑;更稳妥做法是把 mod 设为 0 并在函数内判断)
  • 乘法中间结果必须及时取模,否则 half * half 可能溢出 long long
  • 指数为 0 时返回 1 % mod,确保模 1 场景下也返回 0

迭代版快速幂(推荐用于生产环境)

避免递归开销与栈溢出风险,控制流清晰,易于嵌入循环或中断场景:

long long quick_pow_iter(long long base, long long exp, long long mod = 0) {
    if (mod == 0) mod = LLONG_MAX; // 不模时设为极大值,避免取模运算
    long long res = 1 % mod;
    base %= mod;
    while (exp > 0) {
        if (exp & 1) res = (__int128)res * base % mod; // 防止乘法溢出,用 __int128(GCC/Clang)
        base = (__int128)base * base % mod;
        exp >>= 1;
    }
    return res;
}
  • __int128 是 GCC/Clang 扩展,用于临时容纳 long long * long long 结果;若编译器不支持,需手动拆乘或用 mul_mod 函数模拟
  • 必须先做 base %= mod,否则后续平方会失控
  • 初始 res = 1 % mod 处理 mod == 1 的边界情况

常见错误:溢出、负指数、无模大数输出

这三个问题最常导致 WA 或运行时异常:

BibiGPT-哔哔终结者

BibiGPT-哔哔终结者

B站视频总结器-一键总结 音视频内容

下载

立即学习C++免费学习笔记(深入)”;

  • 直接用 intbaseexp:指数超过 2^31 就截断,应统一用 long long
  • 忽略 base 本身可能为负:取模前应先 base = (base % mod + mod) % mod 归一化到 [0, mod)
  • 需要输出完整大数(而非模结果)时,不能用快速幂直接算——2^1000000 有约 30 万位,得用高精度数组或 std::vector 模拟,快速幂结构仍可用,但乘法要重写

真正的大数幂(无模、全精度)不是“快”就能解决的,而是“存不下”,这点容易被标题里的“快速”二字误导。

https://www.php.cn/faq/1967894.html

发表回复

Your email address will not be published. Required fields are marked *