/**
* 求一个数的整数次方
*/
public class PowerOperator {
/**
* 问题:求一个数的整数次方
*
* @param base 基数
* @param exponent 指数
*/
public static double power(double base, int exponent) {
double precision = 0.000001;
if (equals(base,0.0,precision) && exponent <= 0) {
return 0.0;
}
int positiveExponent = exponent < 0 ? -exponent : exponent;
// double result = powerWithPositiveExponent(base, positiveExponent);
double result = powerWithPositiveExponent2(base, positiveExponent);
if (exponent < 0) {
result = 1.0/result;
}
return result;
}
/**
* 获取base的positiveExponent次方
*
* @param base 基数
* @param positiveExponent 正指数
* @return
*/
public static double powerWithPositiveExponent(double base, int positiveExponent) {
double result = 1.0;
for (int i = 1; i <= positiveExponent; i++) {
result = result * base;
}
return result;
}
/**
* 思想:
* 1)将运算过程 分解为 多个相同的子运算+其它运算
* 2)相同的子运算只需要计算一次即可,当再次遇到同样的子运算时,复用第一次计算的结果,这样可以大大的提高计算的速度。
*
* 公式:
* { a^(n/2) * a^(n/2) n为偶数
* a^n =|
* { a^((n-1)/2) * a^((n-1)/2) * a n为奇数
*
* 注:n为奇数时,n-1为偶数 ==> a^n = a^(n-1) * a = (a^((n-1)/2) * a^((n-1)/2)) * a
*
* @param base 基数
* @param positiveExponent 正指数
* @return
*/
public static double powerWithPositiveExponent2(double base, int positiveExponent) {
if (positiveExponent == 0) return 1;
if (positiveExponent == 1) return base;
double result;
if ((positiveExponent & 1) == 1) { // positiveExponent为奇数
double temp = powerWithPositiveExponent2(base, (positiveExponent-1) >> 2);
result = temp * temp * base;
} else {
double temp = powerWithPositiveExponent2(base, positiveExponent >> 2);
result = temp * temp;
}
return result;
}
/**
* 计算机在表示小数(float/double)时会有一定的误差。
*
* 当二者之差的绝对值小于精度时,我们认为这两个数相等。
*
* @param num1
* @param num2
* @param precision 精度
* @return
*/
public static boolean equals(double num1, double num2, double precision) {
if (-precision <= num1 - num2 && num1 - num2 <= precision) {
return true;
}
return false;
}
public static void main(String[] args) {
double result = power(2, 4);
double result2 = power(2, -4);
System.out.println(result);
System.out.println(result2);
}
}