• 《剑指offer》第十六题(数值的整数次方)


    // 面试题:数值的整数次方
    // 题目:实现函数double Power(double base, int exponent),求base的exponent
    // 次方。不得使用库函数,同时不需要考虑大数问题。
    
    #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)//这个函数返回0同时改变g_InvalidInput,后面判断为啥为0时候,这个变量会告诉我们是base=0且指数为负的错误
        {
            g_InvalidInput = true;
            return 0.0;//第一种情况:base=0
        }
    
        unsigned int absExponent = (unsigned int)(exponent);
        if (exponent < 0)
            absExponent = (unsigned int)(-exponent);//如果不再加负号,absExponent会变成exponent的补数
    
        double result = PowerWithUnsignedExponent(base, absExponent);
        if (exponent < 0)
            result = 1.0 / result;//第二种情况:absExponent<0
                                  //第三种情况:absExponent>=0
        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)//计算base不为0,exponent为非负数情况下的幂值
    {
        if (exponent == 0)
            return 1;
        if (exponent == 1)
            return base;
    
        double result = PowerWithUnsignedExponent(base, exponent >> 1);//使用右移作为除2操作,会很快,exponent为正,所以不怕右移
        result *= result;
        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;
    }
    
    // ====================测试代码====================
    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);
        system("pause");
        return 0;
    }
  • 相关阅读:
    如何通过npm编译Typescript代码
    TypeScript 中的':' 和'?:'的区别
    无法读取本地服务器JSON文件, 返回404错误
    Nodejs , npn 注册 包上传,更新,下载
    Java 字符流
    Java 字节流
    Java中的File类,递归是什么?
    JDBC工具类—如何封装JDBC
    JDBC的开发步骤
    vFor和vIf不要一起使用
  • 原文地址:https://www.cnblogs.com/CJT-blog/p/10480565.html
Copyright © 2020-2023  润新知