面试题16:数值的整数次方
题目:
实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。
全面但不够高效的代码
// 全局变量:判断返回值是否为异常值
// 比如返回值0.0
// ( base==0.0 && exponent<0 )属于异常情况
bool g_InvalidInput = false;
// 判断两个浮点数是否相等,不能使用"=="
bool equal(double num1, double num2);
// 求base的exponent次方
double PowerWithUnsignedExponent(double base, unsigned int exponent);
double Power(double base, int exponent)
{
g_InvalidInput = false;
// 异常情况
if (equal(base, 0.0) && exponent < 0)
{
g_InvalidInput = true;
return 0.0;
}
// 得到exponent的绝对值
unsigned int absExponent = (unsigned int)(exponent);
if (exponent < 0)
absExponent = (unsigned int)(-exponent);
double result = PowerWithUnsignedExponent(base, absExponent);
if (exponent < 0)
result = 1.0 / result;
return result;
}
double PowerWithUnsignedExponent(double base, unsigned int exponent)
{
// exponent==0
// 程序不进入循环,直接返回1.0
double result = 1.0;
for (int i = 1; i <= exponent; ++i)
result *= base;
return result;
}
bool equal(double num1, double num2)
{
if ((num1 - num2 > -0.0000001) && (num1 - num2 < 0.0000001))
return true;
else
return false;
}
double Test1()
{
return Power(2, 3);
}
int main(int argc, char* argv[])
{
double a = Test1();
cout << a << endl;
return 0;
}
既全面又高效的代码
如果输入的指数exponent为32,则在函数PowerWithUnsignedExponent的循环中需要做31次乘法。但我们可以换一种思路考虑:
我们的目标是求出一个数字的32次方,如果我们已经知道了它的16次方,那么只要在16 次方的基础上再平方一次就可以了。而16次方是8次方的平方。
这样以此类推,我们求32次方只需要做5次乘法:
先求平方,在平方的基础上求4次方,在4次方的基础上求8次方,在8次方的基础上求16次方最后在16次方的基础上求32次方。
bool g_InvalidInput = false;
bool equal(double num1, double num2);
double PowerWithUnsignedExponent(double base, unsigned int exponent);
double Power(double base, int exponent)
{
g_InvalidInput = false;
if (equal(base, 0.0) && exponent < 0)
{
g_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)
result = 1.0 / result;
return result;
}
double PowerWithUnsignedExponent(double base, unsigned int exponent)
{
if (exponent == 0)
return 1;
if (exponent == 1)
return base;
double result = PowerWithUnsignedExponent(base, exponent >> 1);
result *= result;
// 考虑exponent是否是奇数,如果是奇数,在除法运算中会损失一次操作
if ((exponent & 0x1) == 1)
result *= base;
return result;
}
bool equal(double num1, double num2)
{
if ((num1 - num2 > -0.0000001) && (num1 - num2 < 0.0000001))
return true;
else
return false;
}
double Test1()
{
return Power(2, 3);
}
int main(int argc, char* argv[])
{
double a = Test1();
cout << a << endl;
return 0;
}