数值的整数次方:
题目描述:
给定一个double类型的浮点数和int类型的整数exponent。求base的exponent次方。
方法1:二分幂
如计算base^exponent;如果exponent为偶数,则计算base^exponent/2(递归到exponent=0),再计算(base^exponent/2)*(base^exponent/2),就可以得出结果;
如果exponent为奇数,则先计算base^(exponent-1)/2(递归到exponent=0),
再计算(base^(exponent-1)/2)*(base^(exponent-1)/2)*base,就可以得出结果.
运行时间为51ms
/**
* 方法1:二分幂
* 如计算base^exponent;如果exponent为偶数,则计算base^exponent/2(递归到exponent=0),再计算(base^exponent/2)*(base^exponent/2),就可以得出结果;
* 如果exponent为奇数,则先计算base^(exponent-1)/2(递归到exponent=0),再计算(base^(exponent-1)/2)*(base^(exponent-1)/2)*base,就可以得出结果.
* 运行时间为51ms
*/
public double Power(double base, int exponent){
if(exponent == 0){
return 1;
}
if(exponent==1){
return base;
}
int exp = exponent>0 ?exponent:-exponent;
double res = Power(base,exp/2);
res *= res;
if(exp%2 == 1){
res *= base;
}
return (exponent>0)?res:1/res;
}
方法二:位运算
假如要计算x^y(设x=3,y=35)
y的二进制表示为100011
那么x^y=(x^32)*(x^2)*(x^1)
解释一下
我们将100011(35的二进制值)从右向左看:最右边的1代表1,第二个代表2,第三个代表4...最后一个代表32
从右向左依次为1,2,4,8,16,32
正好有如下规律:
x^1 *x^1 = x^2;
x^2*x^2 = x^4;
x^4*x^4 = x^8;
1,2,4,8,正好对应8位二进制数的每一位代表的数字
定义两个变量,一个用作记录结果res,一个用作记录幂数写为二进制时,所对应的每一位二进制数时该位置的x的n次方,记为tmp。
通过判断作为幂数的数字的二进制表示从低到高位,是不是1,是1就将这时的x的n次方乘以之前的res,并存入res
//下面的算法运行时间为54ms
public double Power2(double base, int exponent){
double res=1;
double tmp=base;
if(base == 0){
return 0;
}
int n = exponent>0?exponent:-exponent;
if(n==0){
return 1;
}
while(n!=0){
if((n&1) == 1) //判断幂数的二进制形式的最后一位是否为1,为1,则改变返回值
res *=tmp;
tmp *= tmp; //实现算法"x^1 * x^1 = x^2,x^2 * x^2 = x^4 ..."
n>>=1;//右移幂数的二进制形式,向右移一位
}
return exponent>0?res:1/res;
}
更多的计算数值的整数次方,可以参考http://blog.csdn.net/tcm_zhangpeng/article/details/49737509