java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Java中的幂运算(幂函数)

Java中如何编写一个数的n次方(幂运算)?

作者:拼搏@

本文介绍了使用pow函数和自定义for循环计算幂的O(n)时间复杂度方法,然后重点讲解了快速幂算法的分治思想,以及从二进制角度的解释,包括如何通过位运算和循环迭代实现高效计算,给出了Java代码实现

本文介绍了使用pow函数和自定义for循环计算幂的O(n)时间复杂度方法,然后重点讲解了快速幂算法的分治思想,以及从二进制角度的解释,包括如何通过位运算和循环迭代实现高效计算,给出了Java代码实现,

一、算法简介

1.使用pow函数和自定义的for循环的时间复杂度为O(n)

/**计算x的y次方**/
//1.使用Pow函数
double res = Math.pow(x,y);
//2.自定义for循环
double res=x;
for(int i=1;i<y;i++){
     res=res*x;
}

2.快速幂的时间复杂度为O(log n)

二、快速幂的思想

(1)从分冶的角度出发,计算 x^{y}

①假设y为偶数,即计算 3^{8}

3^{8}=3^{2*4}=9^{4}=9^{2*2}=81^{2}=6561^{1}

我们将指数 y,每次划分为 \frac{y}{2},上述式子不需要进行8次循环,而只需要三步即可完 成,注 3^{2*4}9^{2*2}是为了让读者好理解,而重复写的。

②假设y为奇数,即计算 3^{11}

3^{11}=3^{1+10}=3*3^{10}=3*9^{5}=3*9^{1+4}=3*9*81^{2}=3*9*6561^{1}

指数部分为奇数是可以化解成(1+偶数)的形式的,这样我们可以把指数为1的底 拿出来当答案来乘,偶数部分同①继续化解即可

伪代码
    x=3,y=10,res=1
   while(指数y不等于0){
    if(指数y为奇数){
        res = res * x //提取底数出来,作为乘积
    }
    y=y/2 //指数二分
    x=x*x //底数平方

}

(2) 从二进制的角度出发

如8的二进制位:8=1000_{2}

二进制转十进制:1000_{2}=1*2^3+0*2^2+0*2^1+0*2^0=8

那么3^8=3^{(1000)_{2}}=3^{1*2^3+0*2^2+0*2^1+0*2^0}=3^{0*2^0}*3^{0*2^1}*3^{0*2^2}*3^{1*2^3}(倒序写)

观察发现:指数部分是由两部分组成,第一部分是0001,第二部分2^0,2^1,2^2,2^3,发现2是循环增大的(用代码x=x*x,循环迭代出来,但是否使用则看二进制位是否为‘1’),由于二进制要么为0要么为1(用代码 y&1==1,来判断)

再举个详细的例子(计算3^{11}):

11=1011

3^{11}=3^{1*2^{0}}*3^{1*2^{1}}*3^{0*2^{2}}*3^{1*2^{3}}=3^{1*1}*3^{1*2}*3^{0*4}*3^{1*8}

伪代码:

 x=3,y=11,res=1

 while( (1011)y从尾往头读取){

  if( (y&1)==1){

     res=res*x;  //二进制位不为0,则相乘

     //如第一个1:res=1*3,    

     //第二个1:res=res*3^2

     //第三个数为0:不相乘,但x是不断平方的,此时是x^4

     //第四个数为1:res=res*3^8  ,注意哦,平方是在if后面

       }

    二进制右移一位

    x=x*x; //依次迭代3^0,3^1,3^2,3^4,3^8................

 }

三、代码实现

   public static double FastPow(int x,int y){
        double res= 1;
        while (y!=0){ 
            if(y%2 == 1){ //指数为奇数,也可以利用位运算:(y&1)==1 (与操作): 判断 n 二进制最右一位是否为 1
                res *= x;
            }
            y=y/2;  //指数循环二分,y>>=1 (移位操作): n 右移一位(可理解为删除最后一位,即除以2)。
            x=x*x;  //底数平分

        }
        return res;
    }

 

到此这篇关于Java中如何编写一个数的n次方(幂运算)?的文章就介绍到这了,更多相关Java中的幂运算(幂函数)内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

阅读全文