数值的整数次方

剑指Offer面试题11

题目:
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。

分析:
考虑不够全面的错误思路:
由于不考虑大数的问题,有一种简单的思路直接相乘。
但是这个没有考虑到指数是0或者指数小于1的情况,只考虑了指数是正数的情况。

double Power(double base,int exponent)
{
    double result = 1.0;
    for(int i = 1;i <= exponent;i++)
    {
        result *= base;
    }
    return result;
}

全面但不够高效的方法:

1、先判断指数是否为负数,用flag来记录指数的正负
2、求出指数的绝对值,并求出指数为正数的情况下的结果
3、判断指数是不是负数,是负数,则取倒数
4、提示:实数相等的判断,参考equal函数。

class Solution {
public:
    //判断两个实数是否相同
    bool equal(double a,double b)
    {
        if(abs(a - b) < 0.0000001)
        {
            return true;    
        }
        else
        {
            return false;    
        }
    }

    double Power(double base, int exponent) 
    {
        double result = 1.0;        //来存储最后的结果
        bool flag = 1;              //用来判断是不是负数的情况
        unsigned int absExponent = (unsigned int)(exponent);    //absExponent用来保存取绝对值后的数值

        if(exponent == 0)
        {
            return result;
        }

        //由于此处要判断浮点数类型的相等,需要写一个equal()函数来判断
        //当底数为0且指数为负数时,会造成分母是0的情况,会导致程序运行出错
        if(equal(base,0.0) && exponent < 0)
        {
            return -123;    
        }

        //用absExponent 来保存指数的绝对值
        if(exponent < 0)
        {
            flag = 0;
            absExponent = (unsigned int)(- exponent);
        }

        //算出指数为正数的情况下的结果
        for(int i = 0;i < absExponent;i++)
        {
            result *= base;    
        }

        //判断指数是否是负数的情况,若是,结果取倒数
        if(flag == 0)
        {
            result = 1.0/result;    
        }
        return result;
    }
};

全面且高效的方法:
如果输入的指数为32,我们在函数中写的循环中要做31次乘法。
我们可以换个思路:
1、目标是求一个整数的32次方,可以先计算它的16次方
2、然后在16次方上再平方一次就可以了
3、而16次方是8次方的平方
4、这样以此类推。求32次方要进行5次乘法,先求平方,在平方的基础上求4次方,在4次方的基础上求8次方,在8次方的基础上求16次方,在16次方的基础上求32次方。

所以可以用一下公式:

这里写图片描述

class Solution 
{
public:
    //指数为整数时的计算方法     
    double PowerWithUnsignedExponent(double base,unsigned int exponent)
    {
        if(exponent == 0)
        {
            return 1;
        }
        if(exponent == 1)
        {
            return base;
        }

        //此处采用位与运算来代替除以2。因为位运算的效率比乘除法及求余运算的效率要高很多。
        double result = PowerWithUnsignedExponent(base,exponent >> 1);
        result *= result;

        //指数为奇数的情况
        if(exponent & 0x1 == 1)
        {
            result *= base;    
        }
        return result;
    }


    bool equal(double a,double b)
    {
        if(abs(a - b) < 0.0000001)
        {
            return true;   
        }
        else
        {
            return false;   
        }
    }

    double Power(double base, int exponent) 
    {
        //absExponent用来保存取绝对值后的数值  
        unsigned int absExponent = (unsigned int)(exponent);      

        //由于此处要判断浮点数类型的相等,需要写一个equal()函数来判断
        //当底数为0且指数为负数时,会造成分母是0的情况,会导致程序运行出错
        if(equal(base,0.0) && exponent < 0)
        {
            return 0.0;   
        }

        if(exponent < 0)
        {
            absExponent = (unsigned int)(- exponent);    
        }

        double result = PowerWithUnsignedExponent(base,absExponent);
        if(exponent < 0)
        {
            result = 1.0/result;    
        }
        return result;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值