【刷题】P110剑指offer:位运算:面试题16:数值的整数次方

面试题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;
}

猜你喜欢

转载自blog.csdn.net/m0_46613023/article/details/114932279
今日推荐