インタビューの質問16:値の整数乗
トピック:
関数double Power(double base、int exponent)を実装し、baseの指数累乗を見つけます。ライブラリ関数を使用しないでください。また、多数の問題を考慮する必要もありません。
包括的だが効率的ではないコード
// 全局变量:判断返回值是否为异常值
// 比如返回值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;
}
包括的で効率的なコード
入力指数指数が32の場合、関数PowerWithUnsignedExponentのループで31回の乗算が必要です。しかし、別の方法で考えることができます。
私たちの目標は、数値の32乗を見つけることです。すでに16乗がわかっている場合は、16乗に基づいてもう一度2乗します。16乗は8乗の2乗です。
このように、32乗を見つけるには、5回の乗算を行うだけで済みます。
最初に正方形を見つけ、正方形に基づいて4乗を見つけ、4乗に基づいて8乗を見つけ、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;
}