面试题16:数值的整数次方

一、题目

     实现函数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;
}

猜你喜欢

转载自blog.csdn.net/sinat_36161667/article/details/80786515