剑指offer:面试题11——数值的整数次方
题目:给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。
思路一:for循环计算出数的整数次方,注意一下几点:
1)0的负数次方出错,返回值0,需要定义一个全局变量表示出错状态
2)0的正整数次幂为0
3)<u>在比较base值是否为0或1的时候不能直接base== 1或base== 0,因为计算机中浮点型表示小数时存在误差,(double和float)
因此判断两个小数是否相等必须判断两个值的差的绝对值是否在一个范围内,若在,则判定它相等。
解决比较大小的方法是利用isequal函数,代码如下:
class Solution {
public:
bool isequal(double num1,double num2)
{
if((num1-num2>-0.0000001)
&&(num1-num2<0.0000001)) return true;
else return false;
}
public:
double Power(double base, int exponent) {
bool g_InvalidInput=false; //出错处理
if(exponent == 0)
{
if(isequal(base,0.0)) return 0.0;
else return 1.0;
}
/*注意:这里不能使用如下写法之间判断base是否为0,因为浮点型在计算机内表示小数时存在误差,(double和float)
因此判断两个小数是否相等必须判断两个值的差的绝对值是否在一个范围内,若在,则判定它相等。
if(base == 1)
{
return 1;
}
*/
if(isequal(base,1.0)) return 1.0;
if(exponent<0&&isequal(base,0)) //0没有负数整数次幂,返回出错
{
g_InvalidInput=true;
return 0.0;
}
int i;
double result=base;
if(exponent>0)
{
for(i=2;i<=exponent;i++)
result=result*base;
}
else
{
exponent=0-exponent;
for(i=2;i<=exponent;i++)
result=result*base;
result=1.0/result;
}
return result;
}
};
思路二:
当n为偶数时,an=a(n/2) * a^(n/2);
当n为奇数时,an=a( (n-1)/2) * a^( (n-1)/2) * a ;
因此可以将时间复杂度从O(N)变为O(logN)
使用递归实现
注意:在除2时,可以使用右移的方法
在计算奇偶性时,可以用数&0x1 判断二进制位数是否为1(奇偶)
还要注意此处int型指数为了方便运算转换为了unsigned int型
具体代码如下:
class Solution {
public:
bool isequal(double num1,double num2)
{
if((num1-num2>-0.0000001)
&&(num1-num2<0.0000001)) return true;
else return false;
}
public:
double PowerWithUnsignedExponent(double base,unsigned int exponent)
{
if(exponent==1) return base;
if(exponent ==0) return 1;
//右移代表除2运算,用来提高效率
double result = PowerWithUnsignedExponent(base,exponent>>1);
result*=result;
//与0x1表示判断奇偶,用来提高效率
if(exponent&0x1 == 1)
result *=base;
return result;
}
public:
double Power(double base, int exponent) {
bool g_InvalidInput=false; //出错处理
if(exponent == 0)
{
if(isequal(base,0.0)) return 0.0;
else return 1.0;
}
/*注意:这里不能使用如下写法之间判断base是否为0,因为浮点型在计算机内表示小数时存在误差,(double和float)
因此判断两个小数是否相等必须判断两个值的差的绝对值是否在一个范围内,若在,则判定它相等。
if(base == 1)
{
return 1;
}
*/
if(isequal(base,1.0)) return 1.0;
if(exponent<0&&isequal(base,0)) //0没有负数整数次幂,返回出错
{
g_InvalidInput=true;
return 0.0;
}
int i;
double result=base;
if(exponent>0)
{
//这里有所改变
result=PowerWithUnsignedExponent(base,(unsigned int) exponent);
}
else
{
exponent=0-exponent;
//这里有所改变
result=PowerWithUnsignedExponent(base,(unsigned int) exponent);
result=1.0/result;
}
return result;
}
};