一、题目
实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。
二、解法
分析:由于不需要考虑大数问题,这道题看起来很简单。但是需要特别注意的是:如果输入的指数小于1(0和负数)的时候怎么办?当底数是0且指数是负数的时候怎么处理?
2.1 方法一:不够高效的解法
#include <iostream> #include <iostream> #include <cmath> using namespace std; 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) { 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; } int main() { cout << Power(2, 4); system("pause"); }
2.2 方法二:高效的解法
分析:如果输入的指数exponent为32,则在函数的循环中需要做31次乘法,但我们可以换一种思路考虑:我们的目标是求一个数字的32次方,如果我们已经知道了它的16次方,那么只要在16次方的基础上在平方一次就可以了,而16次方是8次方的平方,这样类推,我们求32次方只需要做5次乘法:先求平方,在平方的基础上求4次方,在4次方的基础上求8次方,在8次方的基础上求16次方,在16次方的基础上求32次方。
也就是说,我们可以用如下公式求a的n次方:
这个公式可以在O(log n)的时间求出指数的解。
将上面的 PowerWithUnsignedExponent函数修改如下:
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; if ((exponent & 0x1) == 1) result *= base; return result; }