快速幂 求x的n次幂

Posted 戚焱

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了快速幂 求x的n次幂相关的知识,希望对你有一定的参考价值。

先来看一下&与>>

&

&运算通常用于二进制取位操作,例如一个数 & 1 的结果就是取二进制的最末位。
还可以判断奇偶x&1->0,x为偶数。x&1->1,x为奇数。

>>

将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃。
a=a>>2 将a的二进制位右移2位,左补0 或者 左补1得看被移数是正还是负。
操作数每右移一位,相当于该数除以2。

原理

首先,快速幂的目的就是做到快速求幂,假设我们要求a^b,按照朴素算法就是把a连乘b次,这样一来时间复杂度是O(b)也即是O(n)级别,快速幂能做到O(logn),快了好多好多。它的原理如下:

假设我们要求a^b  ,那么其实b是可以拆分为二进制的,
例如当b==11时,11的二进制是1011,11 = 2^3×1 + 2^2×0 + 2^1×1 + 2^0×1,
因此,我们将a^11转化为算 a2^0 * a2^1 * a2^3,也就是a1*a2*a8, a11=a(2^0+2^1+2^3)。
原来算11次,现在算3次。

代码

class Solution 
    public double myPow(double x, int n) 
        if(x == 0) return 0;
        long b = n;
        double res = 1.0;
        //处理负数
        if(b < 0) 
            x = 1 / x;
            b = -b;
        
        
        while(b > 0) 
            //任何数m&1得x二进制的最后一位,即0或1
            //如果为1,使res乘x。如果求x的11次幂,且此次是第三次循环,那么x此时为x^8
            if((b & 1) == 1) res *= x;
            //x每次变大,如果第一次循环x*x->x^2,第二次就是x^2*x^2->x^4,第三次为x^4*x^4->x^8
            x *= x;
            //右移以求最后一位
            b >>= 1;
        
        return res;
    


比如求解2的11次幂,那么x为2,n为11。11的二进制位1011,需循环四次,
● 第一次 res *= x -> 1 * 2 ->2 ,x *= x -> 4
● 第二次 res *= x -> 2 * 4 -> 8 , x *= x ->16
● 第三次 b&1-> 0 res不变 x * x -> 256
● 第四次 res *= x -> 8 * 256 -> 2048 , x *= x -> 65536

以上是关于快速幂 求x的n次幂的主要内容,如果未能解决你的问题,请参考以下文章

HDU 5895 矩阵快速幂+高次幂取模

算法浅析JavaScript中快速幂操作的使用

数论—快速幂算法

快速幂求解

矩阵快速幂

快速幂