剑指offer-数值的整数次方
题目:数值的整数次方
题目描述:给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
思路:这同样是一道二进制的题
首先考察特殊情况,把0的0次幂,0的负数次幂的情况排除掉,再将负的幂指数先转化成正的算
做完这些以后来进行求次方,对于一个数,如3^5,我们知道计算机中运行最快的操作是移位操作,如果能将这种连乘的转化成移位可以大大提高运算速度
首先,5=(0101),所以3^5=3^4*3^1,所以我们现在只需要求出3^1,3^4的值,我们先从右边算起,在算出3^1后,只需将结果进行2次翻倍,就可以得到3^4,最后将3^1*3^4便可得结果
1 public class Solution { 2 public double Power(double base, int exponent) { 3 double res=1; 4 int n; 5 if(exponent>0){ 6 n=exponent; 7 }else if(exponent<0){ 8 if(base==0) 9 throw new RuntimeException("幂指数为负数时,底数不能为0"); 10 n=-exponent; 11 }else{ 12 if(base==0) 13 throw new RuntimeException("0的0次幂没有意义"); 14 return 1; 15 } 16 //上面的一顿操作已经将0的0次幂,0的负数次幂这些特殊情况作了处理,并将负数次幂先转化为正的 17 //下面通过连乘来求次方 18 while(n!=0){ 19 if((n&1)==1)res*=base; 20 base*=base; 21 n=n>>1; 22 } 23 return exponent>0?res:1/res; 24 } 25 }
注意:一般二进制的题都有多种解法,对于这个题来说,由于底数是double型的,所以在判断底数是否为0时,有时候是不能直接判断的base==0?,需要自己加个精度范围判断,如
boolean equal(double num1,double num2){ if(num1-num2>-0.000001&&num1-num2<0.000001) return true; else return false; }
还有一种做法是直接通过累乘来算,这种时间复杂度O(n),但是计算机在算每步的result*base时,由于不存在移位,直接乘是浪费了不少时间的
for (int i = 0; i < Math.abs(exponent); i++) { result *= base; }