《剑指offer》第十六题:数值的整数次方

复制代码
// 面试题16:数值的整数次方
// 题目:实现函数double Power(double base, int exponent),求base的exponent
// 次方。不得使用库函数,同时不需要考虑大数问题。

#include <iostream>
#include <cmath>

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;
    //底数为0且指数为负数
    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;
}
*/

double PowerWithUnsignedExponent(double base, unsigned int exponent)
{
    if (exponent == 0)
        return 1;
    if (exponent == 1)
        return base;

    //利用二进制求n/2或者(n-1)/2
    double result = PowerWithUnsignedExponent(base, exponent >> 1);
    result *= result; //如果指数为偶数
    if ((exponent & 0x1) == 1) //如果指数为奇数
        result *= base;
 
    return result;
}

bool equal(double num1, double num2)
{
    //精度原因不能直接使用==比较两个double类型的大小
    if ((num1 - num2 > -0.0000001) && (num1 - num2 < 0.0000001))
        return true;
    else
        return false;
}
复制代码
复制代码
// ====================测试代码====================
void Test(const char* testName, double base, int exponent, double expectedResult, bool expectedFlag)
{
    double result = Power(base, exponent);
    if (equal(result, expectedResult) && g_InvalidInput == expectedFlag)
        std::cout << testName << " passed" << std::endl;
    else
        std::cout << testName << " FAILED" << std::endl;
}

int main(int argc, char* argv[])
{
    // 底数、指数都为正数
    Test("Test1", 2, 3, 8, false);

    // 底数为负数、指数为正数
    Test("Test2", -2, 3, -8, false);

    // 指数为负数
    Test("Test3", 2, -3, 0.125, false);

    // 指数为0
    Test("Test4", 2, 0, 1, false);

    // 底数、指数都为0
    Test("Test5", 0, 0, 1, false);

    // 底数为0、指数为正数
    Test("Test6", 0, 4, 0, false);

    // 底数为0、指数为负数
    Test("Test7", 0, -4, 0, true);

    return 0;
}
测试代码
复制代码

分析:考虑问题需要全面,同时注意细节。 

复制代码
class Solution {
public:
    double Power(double base, int exponent) {
    
        if ((base - 0.0) < 0.000001 && (base - 0.0) > -0.000001 && exponent < 0)
            return 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;
        if ((exponent & 0x1) == 1)
            result *= base;
        
        return result;
    }
};
牛客网提交代码
复制代码

 

posted @   源周率  阅读(146)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示