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》