题目描述:
实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。
示例1:
输入: 2.00000, 10
输出: 1024.00000
示例2:
输入: 2.10000, 3
输出: 9.26100
示例3:
输入: 2.00000, -2
输出: 0.25000
解释: 2^(-2) = 1/(2^2) = 1/4 = 0.25
解题思路:
这道题可以借鉴剑指 Offer 15. 二进制中1的个数的思路,这样可以快速计算出指数exponent
的数值,这样可以减少base
进行乘运算的次数,不过这里需要考虑几种特殊情况:
(1)exponent
为负数且base
等于0;
(2)base
等于0且exponent
为0;同时当exponent
为负数时将其转化为正数时要考虑到转化后溢出的情况(exponent=-2^(31)
),因此exponent
要提前强转为long
类型。
这种思路采用两种实现方式,分别是解法1和解法2,解法3是常规做法。
实现代码:
//解法1:快速幂法
public double myPow(double x, int n) {
if(n == 0 || x == 1.0)
return 1;
long m = n;//防止-2^31转为2^31时溢出
double res = 1.0;
if(m < 0 && x == 0.0)
return 0;
if(m < 0){
x = 1 / x;
m = -m;
}
while(m > 0){
if((m & 1) == 1)
res = res * x;
x *= x;
m = m >> 1;
}
return res;
}
//解法2:快速幂法的递归写法
public double myPow1(double x, int n) {
if(n == 0 || x == 1.0)
return 1;
long m = n;//防止-2^31转为2^31时溢出
if(m < 0 && x == 0.0)
return 0;
if(m < 0)
return 1 / pow1(x, -m);
return pow1(x, m);
}
public double pow1(double x, long n){
if(n == 1)
return x;
double square = pow1(x, n / 2);
if((n & 1) == 1)
return square * square * x;
return square * square;
}
//解法3:常规解法(这种解法会超时)
public double myPow2(double x, int n) {
if(n == 0 || x == 1.0)
return 1;
long m = n;//防止-2^31转为2^31时溢出
if(m < 0 && x == 0.0)
return 0;
if(m < 0)
return 1 / pow2(x, -m);
return pow2(x, m);
}
public double pow2(double x, long n){
double res = 1.0;
while(n-- > 0)
res *= x;
return res;
}