题意描述:实现函数double Power(double base, int exp),求base的exp次方,不得使用库函数,同时不用考虑大数问题
解题思路:这样的题目就是自己实现power库函数,通常情况下会直接写出如下代码:
double Power(double base, int exponent) {
double result = 1;
for (int i = 0; i < exponent; ++i)
result *= base;
return result;
}
该方法是最容易想出来的,但存在一定的问题---没有考虑exp为负数问题。下面分析一种比较好的思路:如果输入的指数exp为32,我们在用上面的方法计算时需要循环31次乘法,但可以改进为(16)^2,而16又是8的平方,依次下来求32的平方只需要做5次乘法:先求平方-根据平方求4次方-根据4次方求8次方-根据8次方求16次方-根据16次方求32次方。所以有如下代码:
bool equal(double num1, double num2) {//判断两个double类型的数据是否相等
if (abs(num1 - num2) < 0.0000001)
return true;
else return false;
}
double PowerWithUnsignedExponent(double base, int exp) {
if (exp == 0)
return 1;
if (exp == 1)
return base;
double result = PowerWithUnsignedExponent(base, exp >> 1);//移位运算符代替除法,效率大大提高
result *= result;//对上一步结果求平方
if (exp & 0x1 == 1)//判断奇偶,如果是奇最后还得乘一次基数
result *= base;
return result;
}
bool g_InvalidInput = false;
double Power(double base, int exp) {
g_InvalidInput = false;
if (equal(base, 0.0) && exp < 0) {
g_InvalidInput = true;
return 0.0;
}
unsigned int absExponent = (unsigned int)(exp);
if (exp < 0)
absExponent = (unsigned int)(-exp);
double result = PowerWithUnsignedExponent(base, absExponent);
if (exp < 0)
result = 1.0 / result;
return result;
}
上面的解题方法中用到的技巧:
(1)右移一位代替除2操作,位运算比乘除法效率高;
(2)任何数与0x1与得到二进制最低位进而判断奇偶;
(3)double类型的数字判等时不用直接使用“==”,而是求两数的绝对值之差跟一个小数比较,如小于0.0000001就可认为相等