题目:
实现 pow(x, n) ,即计算 x
的整数 n
次幂函数(即,x^n )。
要明确的是,输入的情况:
给定两个整数
x
和n
,需要计算x
的n
次方。这里需要注意几个特殊情况:
- 当
n
为正数时,计算x^n
- 当
n
为负数时,计算1/(x^(-n))
- 当
x
为 0 且n
为负数时,返回错误(0 的负数次方没有定义)- 当
n
为 0 时,返回 1(任何数的 0 次方都是 1)
先上代码:
public class no_50 {
public static void main(String[] args) {
double x = 2.00000;
int n = -2147483648;
System.out.println(myPow(x, n));
}
public static double myPow(double x, int n) {
if (n == 0)
return 1;
if (x == 0)
return 0;
Long N = (long) n;
if (N < 0) {
x = 1 / x;
N = -N;
}
double re = 1;
while (N > 0) {
if (((N & 1) == 1)) {
re *= x;
}
x *= x;
N >>= 1;
}
return re;
}
}
可能会有疑问,当实际计算的时候,采用策略进行计算加速,尤其是,当x为偶数和奇数时要分开,为什么要用这样的思路?实际上这是一个数学思路叫做快速幂算法。
快速幂算法的数学原理
快速幂算法的核心思想是将指数 n 按二进制位来拆分,利用二进制的特性来加速计算。来看一个例子:
假设要计算 x^13,可以将 13 表示为二进制:
13 = (1101)_2
那么 x^13 可以表示为:
x^13 = x^(8 + 4 + 1) = x^8 * x^4 * x^1
可以发现,每一项都是 x 的 2 的幂次方。这样就可以通过平方和乘法来计算 x^13 了。
具体来说:
1. x^8 可以通过 (x^4)^2 来计算
2. x^4 可以通过 (x^2)^2 来计算
3. x^2 可以通过 x * x 来计算所以最终的计算过程是:
1. 计算 x^2
2. 计算 x^4 = (x^2)^2
3. 计算 x^8 = (x^4)^2
4. 计算 x^13 = x^8 * x^4 * x这种方式比直接计算 x^13 要高效得多,因为它只需要 O(log n) 次乘方和平方操作,而直接计算需要 O(n) 次乘法操作。
之所以要区分偶数和奇数,是因为在二进制表示中:
- 偶数的最低位一定是 0,可以通过右移一位(相当于除以 2)来消去最低位的 0
- 奇数的最低位一定是 1,需要将当前的 x 乘入结果中,并将 n 减 1 来消去最低位的 1通过这种方式,我们可以一步步将 n 降低为 0,同时计算出 x^n 的值。
所以快速幂算法的数学原理就是利用二进制位的特性,将幂运算转化为一系列平方和乘法操作,从而加速计算。