数值的整数次方

题目描述
给定一个double类型的浮点数base和int类型的整数exponent。求base的exponent次方。

思路:
 base:+ - 0;exponent : + - 0;
 base的正负号影响并不大,倒是等于0会产生较大的影响,就是对0exponent的讨论。产生的问题是0负数,是一个错误的输入。
 假设base不为0,接下来就是对exponent的分别讨论了。

  • 1。 最终结果也是1.
  • 正数。 直接乘,得出结果。例如 25,就是2 * 2 * 2 * 2 * 2;
  • 负数。 先转换成正数的运算,最后再让 1 除以正数的结果,就得到我们需要的结果。

代码如下:

class Solution {
public:
    double Power(double base, int exponent) {
        int n;
        bool minus = false;
        long double result, temp;//考虑大数,有可能会产生溢出,所以这里使用 long double
        
        //如果 base 是0的话,就会产生问题
        if (exponent == 0){
            return 1;
        } else if (exponent > 0) {
            n = exponent;
        } else {
            n = -exponent;
            minus = true;
        }
        
        result = 1;//使用之前记得进行初始化
        for (int index = 1; index <= n; index++)
        {
            result *= base;
        }
        
        return (minus == false) ? result : 1 / result;
    }
};

 修改一下,上述代码运算次数比较多,例如28要进行7次乘法运算,可以想办法让乘法运算次数减少。采用指数增长法,每次乘完之后的数字保存起来,以方便进行下一次乘法运算。举例说明:还是28,2 * 2 存储到temp中,幂指数增长,下次执行temp = temp * temp。(到这里想法还不是很成熟)
代码如下:

class Solution {
public:
    double Power(double base, int exponent) {
        int n, index;
        bool minus = false;
        long double result, temp;//有可能会产生溢出,所以这里使用 long double
        
        //如果 base 是0的话,就会产生问题
        if (exponent == 0){
            return 1;
        } else if (exponent > 0) {
            n = exponent;
        } else {
            n = -exponent;
            minus = true;
        }
        
        //考虑一个问题,如果遍历的速度是很慢的,假如是8,要进行7次乘法运算
        //那么可以让他增长速度更快一点,采用2的指数递增法,假如是8,要进行3次乘法运算
        temp = base;//使用之前记得进行初始化
        for (index = 2; index <= n; index = index * 2)
        {
            temp *= temp;
        }
        
        result = temp;
        if (index > n)
        {
            index = index / 2;
        }
        
        while (n - index)
        {
            result *= base;
            n--;
        }
        
        return (minus == false) ? result : 1 / result;
    }
};

 再多加考虑产生异常输入的问题。
0负数,返回值0.0,与正常输入会产生相同的结果,为了与正常结果进行区分,使用全局变量记录错误产生。
对于一个整数,在内存中是以二进制进行存储的,例如13(0x1101),213=20x0001*20x0100*20x1000;
最终代码如下:

class Solution {
public:
    bool g_InvalidInput = false;
    
    double Power(double base, int exponent) {
        //在使用之前应该先对 g_InvalidInput 进行初始化
        //否则非常有可能使用的是上次程序执行的那个值
        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 = PowerWithAbsExponent(base, absExponent);
        if (exponent < 0) {
            return 1.0/result;
        } else {
            return result;
        }
    }
    
    
private:
    double PowerWithAbsExponent(double base, int exponent)
    {
        if (exponent == 0) {
            return 1.0;
        } else if (exponent == 1) {
            return base;
        }
        /*
        //递归是一直往回倒
        double result = PowerWithAbsExponent(base, exponent >> 1);
        result *= result;
        if ((exponent & 0x1) == 1) {
            result *= base;
        }
        */
        //尝试正向来做
        double temp = base;
        double result = 1.0;
        while (exponent != 0) {
            if ((exponent & 0x01) == 1) {
                result *= temp;
            }
            temp *= temp;
            exponent >>= 1;
        }
        
        return result;
    }
    //由于浮点数在内存存储中会产生一定的误差, 所以浮点数判断相等只要在一个较小的范围内即可
    bool equal(double num1, double num2)
    {
        if ((num1 - num2 < 0.0000001) && (num1 - num2 > -0.0000001)){
            return true;
        } else {
            return false;
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值