用 pow 求 int 的 n 次方多数错误,因其返回 double 导致精度丢失(如 pow(5,2) 可能得 24.999...),整数幂应手写 ipow 循环实现,避免浮点误差并可控溢出。

用 pow 求 int 的 n 次方,多数时候是错的
pow 返回 double,对整数幂运算既不精确也不高效。比如 pow(5, 2) 理论上是 25,但实际可能返回 24.999999999999996,强转 int 后直接变 24。这不是 bug,是浮点计算固有误差 —— 它根本不是为整数幂设计的。
- 只在底数或指数是浮点数(如
2.5、3.0)时才该用pow - 整数底数 + 整数指数 → 优先手写循环或用
std::pow的整数重载(C++11 起有pow(int, int),但仍是隐式转 double,没解决精度问题) - 编译器(如 GCC)对
pow(2, n)可能优化成位移,但别依赖:行为未标准化,且仅限 2 的幂
手写整数幂函数比调 pow 更可靠
自己写一个 ipow,逻辑清晰、无浮点误差、还能控制溢出行为。最简版本就是乘法循环:
int ipow(int base, int exp) {
if (exp < 0) return 0; // 或抛异常,整数负幂结果非整数
int result = 1;
while (exp-- > 0) result *= base;
return result;
}- 注意
exp为 0 时返回 1,符合数学定义 - 必须检查
exp :C++ 中 <code>int无法表示分数,硬算会错 - 没做溢出检测 ——
10^9在int上大概率溢出,实际项目里建议用long long或加std::mul_overflow(C++23)
std::pow 和 std::ipow(C++23)的区别
C++23 引入了 std::ipow(在 <cmath>),专用于整数幂,返回 int 类型,且明确定义了溢出行为(返回 0 或抛 std::overflow_error)。但它要求编译器支持 C++23,且目前主流 STL 实现(libstdc++、libc++)尚未完全落地。
- 用
std::ipow(3, 4)是安全的,但得确认编译环境:g++ -std=c++23+ 较新版本 -
std::pow(3, 4)仍返回double,即使参数是整数 - 别混用:传
long long给std::ipow会编译失败 —— 它只接受int、long、long long等明确整型,不接受浮点
快速幂?真需要时再上,别一上来就抄模板
当 exp 很大(比如 10^6),普通循环要跑百万次,这时才值得上快速幂。但日常 n ≤ 100 完全没必要。
立即学习“C++免费学习笔记(深入)”;
- 快速幂核心是二分思想:
base^exp = (base^(exp/2))^2 × (base if exp odd) - 递归写法易懂但有栈开销;迭代写法稍长但更稳
- 所有快速幂实现都绕不开溢出检查 —— 指数大,底数稍大一点,中间结果就炸了
- 别为了“看起来高级”而用它:99% 的业务代码里,
for循环 10 次比快速幂还快,还少两个 bug
整数幂这事,越想一步到位越容易掉坑里。先想清楚:是不是真要整数结果?指数会不会超 32?要不要负幂?这些问清楚了,选循环还是 std::ipow 自然就定了。









