题目描述:
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
思路:
思路1:
1. 肯定不能调用Math.pow()函数咯,倒是可以用它来测试一下结果是否正确
2. 使用循环重复乘exponent次, 时间复杂度为O(n), 肯定有更加快速的方法
3. 避免重复计算可以减少乘法的计算次数:
a^10 = (a^2)^5 = ((a^2)^2) * a, 计算5次乘法,相较于依次相乘减少了一半之多啊
4. 让指数每次右移一位来代替除法操作
5. 注意负数的右移会存在左边的值全为1的情况,应该先转成正数,再取倒数。
总的来说就是,利用以计算的值、避免重复计算、移位替换除法。
思路2:
1. a^1001 = a^(1000+0001) = a^1000 * a^0001
2. 所以就可以检验每一位是不是零,来决定是否要将他乘入到最后的结果中。
代码
public static double power(double base, int exponent) {
if (exponent == 0)
return 1.0;
if (exponent == 1)
return base;
if (exponent < 0)
return 1 / powerPositive(base, -exponent);
else
return powerPositive(base, exponent);
}
public static double powerPositive(double base, int exponent) {
boolean isEven = false; // 是不是偶数
if ((exponent & 1) == 0)
isEven = true;
double baseSquare = base * base;
exponent = exponent >> 2; // 右移两位。其中一位是上面平方了一次,另一位是在最后决定乘以base还是乘以1.
while (exponent != 0) {
baseSquare = baseSquare * baseSquare;
exponent = exponent >> 1;
}
// 如果是奇数就还需要再乘以一个base
double result = isEven ? baseSquare : baseSquare * base;
return result;
}
public static double powerPositive2(double base, int exponent) {
if(exponent == 0)
return 1.0;
double result = 1.0; //
double curr = base; // 表示当前位置的乘方值
while(exponent != 0) {
if((exponent & 1) == 1) // 如果当前二进制位置的值为1, 就乘进去
result *= curr;
curr *= curr; // 当前位置表示的值大小变为他的平方
exponent = exponent >> 1; // 右移一位哟
}
return result;
}