C++ pow 幂运算

在数学中,计算 “a 的 b 次方” 叫做幂运算,比如计算 2 的 5 次方、10 的 3 次方。与 Python 直接提供 ** 运算符不同,在 C++ 中并没有专门的次方运算符,我们需要调用 <cmath> 头文件中的 std::pow() 函数来实现。

std::pow() 的基本用法

在使用 std::pow() 函数之前,我们需要先通过 #include <cmath> 引入头文件。其中,pow 是英文单词 “power(幂、次方)” 的缩写。

语法:

std::pow(base, exp)

说明:

在 C++ 中,std::pow() 用于计算以 base 为底数、exp 为指数的次方结果,默认返回值类型为 double。它接收以下 2 个参数:

  • base(必选):表示底数,支持传入整数或浮点数。
  • exp(必选):表示指数(即次方数),同样支持传入整数或浮点数。

示例 1:计算整数与小数的次方

#include <cmath>
#include <iostream>

int main() {
    double r1 = std::pow(2.0, 5.0);    // 计算 2.0 的 5 次方
    double r2 = std::pow(10, 3);       // 计算 10 的 3 次方
    double r3 = std::pow(1.5, 2);      // 计算 1.5 的 2 次方

    std::cout << r1 << '\n';
    std::cout << r2 << '\n';
    std::cout << r3 << '\n';
    return 0;
}

运行结果如下。

32
1000
2.25

分析:

上面代码分别计算了 2.0 的 5 次方、10 的 3 次方以及 1.5 的 2 次方。可以看到,std::pow() 既可以接收 double 浮点数,也可以直接传入 int 整数。

需要注意的是,哪怕传入的两个参数都是 int 整数,std::pow() 内部也会先将它们转为 double 再计算。变量 r1 和 r2 保存的依然是 double 类型,屏幕上打印 32 和 1000 只是省略了末尾的 .0。

零次方、负指数与小数指数

除了常见的正整数次方之外,std::pow(base, exp) 的第 2 个参数 exp 还可以传入 0、负数或小数,分别对应数学中的以下 3 种规则:

  • 指数为 0:任何非零数的 0 次方结果都等于 1,比如 5 的 0 次方等于 1。
  • 指数为负数:表示正数次方的倒数,比如 2 的 -3 次方等于 1 除以 2 的 3 次方,即 1 除以 8 等于 0.125。
  • 指数为小数:对应数学中的开方运算,比如 0.5 次方相当于求算术平方根,9 的 0.5 次方等于 3。

下面我们来看一个例子。

示例 2:特殊指数的幂运算

#include <cmath>
#include <iostream>

int main() {
    std::cout << std::pow(5.0, 0.0) << '\n';     // 5.0 的 0 次方
    std::cout << std::pow(2.0, -3.0) << '\n';    // 2.0 的 -3 次方
    std::cout << std::pow(9.0, 0.5) << '\n';     // 9.0 的 0.5 次方
    return 0;
}

运行结果如下。

1
0.125
3

分析:

std::pow(9.0, 0.5) 表示计算 9.0 的 0.5 次方,算出了 9 的算术平方根 3。不过在实际开发中,如果明确只是求算术平方根,我们更推荐直接调用 std::sqrt() 函数。这样不仅代码意图更直观,运算速度也更快。

此外小伙伴们要注意,当底数 base 为负数时,指数 exp 只能传入整数,比如 std::pow(-2, 3) 的结果为 -8。如果给负数底数搭配小数指数,写成 std::pow(-8.0, 1.0 / 3.0),函数会直接返回无效数字 NaN。

为什么不能使用 ^ 计算次方?

平时在键盘上输入数学算式时,很多人习惯把 “2 的 3 次方” 敲成 2^3。不少初学的小伙伴在写 C++ 代码时,也会顺着直觉写出 int res = 2 ^ 3;,结果发现程序虽然不报错,算出来的结果却完全不对。

这是因为在 C++ 中,^ 并不是次方运算符,而是位运算中的按位异或运算符。请看下面例子。

示例 3:对比 ^ 与 std::pow()

#include <cmath>
#include <iostream>

int main() {
    int xorVal = 2 ^ 3;                // 按位异或运算
    double powVal = std::pow(2, 3);    // 计算 2 的 3 次方

    std::cout << xorVal << '\n';
    std::cout << powVal << '\n';
    return 0;
}

运行结果如下。

1
8

分析:

从运行结果可以看出,2 ^ 3 得到的结果是 1 而不是 8。按位异或会把十进制 2(二进制 010)和十进制 3(二进制 011)逐位对比,遵循 “相同为 0、不同为 1” 的规则:

010 ^ 011 -> 001

二进制 001 换算成十进制就是 1。由于 2 ^ 3 在 C++ 语法中完全合法,编译器不会给出报错提醒,一旦写错排查起来很费时间。因此小伙伴们一定要记住:在 C++ 中计算次方统一调用 std::pow(),千万不要写成 ^。

整数平方与立方的写法选择

如果只是计算一个普通整数的平方或立方,比如已知正方形的整数边长 side 求面积,我们既可以调用 std::pow(side, 2),也可以直接写乘法 side * side。在实际开发中更推荐直接写乘法,主要有以下 2 个原因:

无需转换类型且速度更快:对于 int side = 6;,直接写 int area = side * side; 是一次纯粹的整数乘法,结果本身就是 int 类型。而调用 std::pow(side, 2) 会先把整数转为 double 计算,拿到结果后还需要再做一次类型转换。

避免浮点误差导致截断出错:std::pow() 内部采用浮点数运算。在部分平台下,计算较大整数次方可能产生极微小的浮点误差,比如本该是 100 却算出 99.99999999999999,直接强制转为 int 就会把小数抹掉变成 99。

因此,简单的整数平方、立方优先直接写 x * x 或 x * x * x。当指数较大需要调用 std::pow() 并将结果存入整型变量时,我们可以配合 std::round() 写成 (int)std::round(std::pow(2, 10)),先四舍五入再转换会准确得多。

上一篇:

下一篇:

给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号