快速幂法

1.剑指offer16:数值的整数次方。

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

说明:

  • -100.0 < x < 100.0
  • n 是 32 位有符号整数,其数值范围是 [−231, 231 − 1] 。

https://leetcode-cn.com/problems/shu-zhi-de-zheng-shu-ci-fang-lcof/

class Solution {
    public double myPow(double x, int n) {
        
        long d = n;
        double res = 1.0;
        if(n<0){
            x = 1/x;
            d = -d;
        }
        while(d>0){
            if((d&1)==1)res = res*x;
            x = x*x;
            d = d>>1;
        }
        return res;

        // if(n==0)return 1;
        // if(n<0){
        //     return 1/x*myPow(1/x,-n-1);
        // }
        // return n%2==0? myPow(x*x,n/2):x*myPow(x*x,n/2);
    }
}

解:

指数n可能为负数,取相反数时可能会发生溢出,如  -2^31 取 相反数为2^31 而int的范围为 [−231, 231 − 1] ,所以发生溢出。

所以声明一个long类型的变量 long d  = n;防止溢出。

将指数n拆解为二进制的展开式。

如9 的二进制为 1001;

 

 那么:

 

 可以发现当二进制的某一位为0时,就相当于乘了一个x^0==1. 所以为0时不需要对res变量进行操作,只需要考虑二进制位为1的时候对res进行操作(另外因为x^2 = x*x; x^4 = x^2*x^2……,所以每经过一个循环都要执行x = x*x 操作)

所以我们先声明一个变量res = 1,然后从右向左遍历指数n的二进制中的每一位,当这一位为0时 不对res进行操作,只对x进行操作,另x = x*x;然后指数n的二进制向右移位。当这一位为1时,我们另res = res*x;,然后对x进行操作,在然后对指数n进行移位,直到n==0结束。最终返回res结果变量。

 

posted @ 2020-08-29 10:40  藤原拓海7  阅读(149)  评论(0编辑  收藏  举报