[質問] P110ソードはオファーを指します:ビット演算:インタビュー質問16:値の整数乗

インタビューの質問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;
}

おすすめ

転載: blog.csdn.net/m0_46613023/article/details/114932279