1.题目分析
题目描述
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
保证base和exponent不同时为0——
情况讨论:
1.base可能为0,此时是选择返回值、设置全局变量还是设置异常要根据面试官而定
2.exponent也可能小于0,此时需要取它的绝对值,并且对取绝对值求整数次方的结果取倒数
2.解决方法1.0:只考虑到了输入输入合法时的情况
class Solution {
public:
double Power(double base, int exponent) {
double result = 1.0;
if( exponent < 0)
{
for (int i = 0; i > exponent ; --i)
{
result *= base;
}
result = 1/result;
}else{
for (int i = 1; i <= exponent ; ++i)
{
result *= base;
}
}
return result;
}
};
3.解决方法2.0:解决非法输入以及指数为负的问题
//功能:处理非法输入,以及指数为负数时的结果处理
double Power(double base , int exponent)
{
InvalidInput = false;//默认是没有不法输入的
if (equal(base,0.0) && exponent < 0) //当基数为0且指数小于0时,输入非法,设定其返回0
{
InvalidInput = true;
return 0.0;
}
unsigned int absExponent = (unsigned int)(exponent);//定义一个指数的无符号变量
if (exponent < 0) //当指数为负数时,它的无符号整型是它的相反数
{
absExponent = (unsigned int)(-exponent);
}
double result = PowerWithUnsignedExponent(base,absExponent);//将基数和取绝对值的指数传入求平方函数
if (exponent < 0 )//当指数为负数时 ,得到的结果是指数为正数的倒数
{
double result = (1.0)/result;
}
return result;
}
//功能: 对基数base求Exponent次方
double PowerWithUnsignedExponent(double base,int absExponent)
{//有多少次方就乘上多少个基数base
double result = base;
while(absExponent--)
{
result *=base;
}
return result;
}
//功能:浮点数判断相等不能直接用等于号判断,这里给出了方法
bool equal(double num1,double num2)
{
if ((num1 - num2) > -0.0000001 &&(num1 - num2) < 0.0000001)
{
return true;
}else{
return false;
}
}
4.结局方法3.0:提高效率,利用递归,算术右移
8次方是4次方的自乘,4次方是2次方的自乘,所以可以利用递归来提高效率,计算整数次方的函数可以如下
//功能: 对基数base求Exponent次方
double PowerWithUnsignedExponent(double base,unsigned int absExponent)
{//递归的方法
if(absExponent == 0)
{
return 1.0;
}
if(absExponent == 1)
{
return base;
}
double result = PowerWithUnsignedExponent(base,absExponent >>1 );
result *=result;
if(absExponent &0x1 ==1)//当指数为奇数时需要多乘一次base,前边的算术移位相当于除以2
{
result *= base;
}
return result;
}
提高效率:
- 利用>>算术移位只需要一个时钟周期,除法/需要三十多个时钟周期,所以用exponent >>1
- absExponent &0x1==1是判断奇数偶数的
&是按位与的运算:只有两边都是1的时候结果才为1
0&1=0
1&0=0
0&0=0
1&1=1
0x1是十六进制的1,所以如果指数为奇数,其二进制最后必为1,所以与十六进制相与肯定为1
摘自《剑指offer》