求一个数的n次方。
非递归算法:
unsigned Power( unsigned n, unsigned p )
{
// 计算n的p次
// 把p表示成二进制形式。例如,p=101010
// n^(10) = ( n^(1) )^2
// n^(110) = n^(100)*n^(10) = ( ( n^(1) )^2 )^2 * n^(10)
unsigned k = 1;
while ( p > 1 )
{
if ( 0 != ( p & 1 ) )
{
// 判断p是否为奇数
k *= n;
}
n *= n; // 主体乘方
p /= 2; // 指数除以2
}
return n * k;
}
上面的算法只适用于p>1的情况。
递归算法(divide and conquer):
power(a, n) = power(a, n/2) * power(a, n/2) if n is even;
power(a, (n–1)/2) * power(a, (n–1)/2) * a if n is odd.
递归复杂度方程:T(n) = T(n/2) +1。复杂度:log(n)。下面的算法考虑了n为负数的情况.
double pow(double x, int n) {
if(n<0)
return 1.0/pow(x, -n);
if( n == 0)
return 1;
double temp = pow(x, n/2);
if (n%2 == 0)
return temp*temp;
else
return x*temp*temp;
}
当n为负数时,我们求1.0/pow(x, -n)。但是n=-2^(-31)时,-n会溢出(32bit有符号整数的范围是-2^(-31) ~ 2^31)-1)。下面是更安全的算法, 不对n求-n。。
double pow(double x, int n)
{
if( n == 0)
return 1;
double temp = pow(x, n/2);
if (n%2 == 0)
return temp*temp;
else
{
if(n > 0)
return x*temp*temp;
else
return (temp*temp)/x;
}
}