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. bn={bn/2bn/2b(n1)/2b(n1)/2bnn
递归地计算本身的 n / 2 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 tmpbase=b23=b8。​

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

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

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值