算法思想:
这题我们不难想到可以使用二分法来求解,现在通过一个例子来辅助理解:
求pow(3,19):
由19=(9*2+1)
可以得到:pow(3,19)=(pow(3,9)^2)*pow(3,1)
同理可得
pow(3,9)=(pow(3,4)^2)*pow(3,1)
pow(3,4)=pow(3,2)^2
pow(3,2)=3*3
像这样递归下去直至归化到幂为1,2时即可
当n为负数时同样可以采取这一思路,在此之前我们需要了解一下负数求余的特性:
请看下面一段代码:
int main()
{
cout << "5%3=" << 5 % 3 << endl;
cout << "5%-3=" << 5 % -3 << endl;
cout << "-5%3=" << -5 % 3 << endl;
cout << "-5%-3=" << -5 % -3 << endl;
return 0;
}
运行结果:
可见余数的符号取决于分子
即a%b=sign(a)*(|a|%|b|)
我们同样举个栗子加以说明:
求pow(3,-19)
由-19=-9*2+(-1)
得pow(3,-19)=(pow(3,-9)^2)*pow(3,-1)
pow(3,-9)=(pow(3,-4)^2)*pow(3,-1)
pow(3,-4)=pow(3,-2)^2
pow(3,-2)=pow(3,-1)^2
像这样递归下去直至归化到幂为-1时即可
归纳总结:
对任意一个绝对值大于2的数n都可以写成n=2*(n/2)+n%2的形式,因此当n在上述情况时可以统一用以下公式表述:
pow(x,n)=pow(pow(x,n/2),2)*pow(x,n%2)
为此,只需要讨论n=0,1,-1,2四种情况即可,其他情况都可以通过上述递归公式回归到这四种情形。
代码:
double myPow(double x, int n)
{
//0的任何非零次幂都等于0,假定0^0=0
if (x == 0)
return 0;
if (n == 0)
return 1;
else if (n == 1)
return x;
else if (n == -1)
return (1.0 / x);
else if (n == 2)
return x * x;
else
return myPow(myPow(x, n / 2), 2) * myPow(x, n % 2);//递归计算
}
对于0^0的处理有的计算器设定为1,我假定为0,但一般对其并不作定义,所以对此不必太过纠结。