面试可能会被提问到的一道题——实现浮点数的幂运算,需要考虑到的情况非常多。在实现幂运算的时候,如果只是简单使用迭代的方法,虽然也能得到结果,但是运行效率不高。
第一种方法:使用快速幂,时间复杂度O(logn)
把指数当十进制情况下,需要判断奇数还是偶数
当n为偶数
a
n
=
a
n
/
2
∗
a
n
/
2
a^{n} =a^{n/2}*a^{n/2}
an=an/2∗an/2
当n为奇数,
a
n
=
a
(
n
−
1
)
/
2
∗
a
(
n
−
1
)
/
2
∗
a
a^n = a^{(n-1)/2}* a^{(n-1)/2} * a
an=a(n−1)/2∗a(n−1)/2∗a
举例:
2
11
=
2
1
∗
2
2
∗
2
8
2^{11} = 2^1 * 2^2 * 2^8
211=21∗22∗28
指数当为二进制时,不需要判断奇偶,更方便
2 1011 = 2 0001 ∗ 2 0010 ∗ 2 1000 2^{1011} = 2^{0001} * 2^{0010} * 2^{1000} 21011=20001∗20010∗21000
第二种方法:累乘,时间复杂度为O(n)
2 11 = 2 ∗ 2 ∗ ⋅ ⋅ ⋅ ∗ 2 2^{11} = 2 * 2 * ···*2 211=2∗2∗⋅⋅⋅∗2
快速幂(指数二进制)代码实现
#include <cmath>
#include <limits>
#include <stdexcept>
using namespace std;
class Solution {
public:
double Power(double base, int exponent) {
const double EPS = numeric_limits<double>::epsilon(); // 浮点数最小精度
if (base - 0 < EPS) // base 等于0时
if(exponent > 0) return 0.0;
else throw new invalid_argument("分母不能为0");
if (base - 1 < EPS || exponent == 0) return 1.0; // base 等于0或exponent等于0时
double result = 1.0;
int abs_exponent = abs(exponent);
while (abs_exponent != 0) {
if ((abs_exponent & 1) == 1) result *= base;
base *= base; // 翻倍
abs_exponent >>= 1;// 右移一位
}
return exponent < 0 ? 1 / result : result;
}
};