Q16数值的整数次方

数值的整数次方

题目

实现double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。

思路

需要考虑全面:

  1. 基数为0,指数小于0,由于产生了0的倒数,输入非法!
  2. 指数为0,返回1
  3. 指数为负数,返回值需要变为原来的倒数

更进一步:

  • 二分幂
  • 快速幂
  • 用 移位代替 除2
  • 用 与运算 判断整数是否奇偶

实现

基础版本 实现:

class Solution {
public:
    double Power(double base, int exponent) {
        if(abs(base)<1e-15 && exponent<0)
            return 0; //throw exception
        double result;
        //if(exponent==0)
        //    result = 1.0; //实际已经在下面考虑过了
        //else
        //{
            int absExponent = exponent>=0 ? exponent : -exponent; 
            result = 1;
            while(absExponent--)
            {
                result *= base;
            }
            result = exponent>=0 ? result : 1/result;
        //}
        return result;
    }
};

包含递归二分幂、快速幂和基础版本的实现:

class Solution {
public:
    double Power(double base, int exponent) {
        if(abs(base)<1e-15 && exponent<0)
            return 0; //throw exception
        int absExponent = exponent>=0 ? exponent : -exponent; 
        double result = PowerUnsigned3(base, absExponent);
        result = exponent>=0? result : 1/result;
        return result;
    }
    
    //快速幂
    double PowerUnsigned3(double base, int exp)
    {
        double res = 1;
        double tmpBase = base;
        while(exp)
        {
            if(exp & 0x1)//exp%2==1?
                res *= tmpBase;
            tmpBase *= tmpBase;
            exp >>= 1;  //exp/2
        }
        return res;
    }
    
    //二分幂
    double PowerUnsigned2(double base, int exp)
    {
        if(exp==0) return 1;
        if(exp==1) return base;
        double res = PowerUnsigned2(base, exp>>1); //递归地get power(base, exp/2)
        res *= res; //power(base, exp/2) * power(base, exp/2)
        if(exp&0x1) res*=base; //exp奇数时再乘一下base
        return res;
    }
    
    //普通循环
    double PowerUnsigned1(double base, int exp)
    {
        double res = 1;
        while(exp--)
            res *= base;
        return res;
    }
};

二分幂

https://blog.csdn.net/tcm_zhangpeng/article/details/49737509?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

二分算法

b n = { b n / 2 b n / 2 n b ( n 1 ) / 2 b ( n 1 ) / 2 b n b^n=\left\{ \begin{array}{lcl} b^{n/2}* b^{n/2} & & {n为偶数}\\ b^{(n-1)/2}* b^{(n-1)/2}*b & & {n为奇数}\\ \end{array} \right.
递归地计算本身的 n / 2 n/2 次幂。

快速幂

  • 利用指数的二进制形式,例如b的11次方,exp=11的二进制为 1011,将exp不断向右移位。

  • 每次移位时,将当前的临时tmpbase倍增,也就是说,没移位时,tmpbase为b, 移一次,tmpbase=b*b。*移三次 t m p b a s e = b 2 3 = b 8 tmpbase = b^{2*3}=b^8 。​

  • 在移位过程中当前exp末位为1时,表示参与最终结果,故 res *= tmpbase。

  • 例如,在11的第三次移位中, t m p b a s e = b 4 tmpbase = b^4 ,但是未参与 最终result的计算。

在这里插入图片描述

发布了48 篇原创文章 · 获赞 10 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/mhywoniu/article/details/105393689