Java 平方求幂

Java 平方求幂,java,algorithm,math,Java,Algorithm,Math,当我在搜索时,我得到了递归方法,但后来我偶然发现了这个伪代码,我无法完全理解它 function powermod(base, exponent, modulus) { if (base < 1 || exponent < 0 || modulus < 1) return -1 result = 1; while (exponent > 0) { if ((exponent % 2) == 1) {

当我在搜索时,我得到了递归方法,但后来我偶然发现了这个伪代码,我无法完全理解它

function powermod(base, exponent, modulus) {
    if (base < 1 || exponent < 0 || modulus < 1)
        return -1

    result = 1;
    while (exponent > 0) {
       if ((exponent % 2) == 1) {
           result = (result * base) % modulus;
       }
       base = (base * base) % modulus;
       exponent = floor(exponent / 2);
    }
    return result;
} 
函数powermod(基、指数、模数){ if(基<1 | |指数<0 | |模数<1) 返回-1 结果=1; 而(指数>0){ 如果((指数%2)==1){ 结果=(结果*基础)%模数; } 基底=(基底*基底)%模量; 指数=楼层(指数/2); } 返回结果; }
如果您能简单地给出一些见解,将非常有帮助

代码依赖于以下事实:

x^y == (x*x)^(y/2)
循环正是这样做的:将指数除以2,同时将基数平方

一个例子:

让我们考虑计算3 ^ 13的结果。您可以将指数(13)写成二进制幂和:

3^(8+4+1)
。然后:
3^13=3^8*3^4*3^1

这种二进制幂的分解是由代码中的
%2
/2
使用上述原理来完成的

一步一步:

您可以从
3^13
开始。当
13%2==1
时,将结果乘以
3
,因为答案有一个系数
3^1

然后将指数除以2,并将基数平方(
9^6==3^12
)。由于
6%2==0
,这意味着答案没有系数
3^2

然后将指数除以2,并将基数平方(
81^3==3^12
)。当
3%2==1
时,将结果乘以81,因为答案没有系数
3^4

然后将指数除以2,并将基数平方(
6561^1==3^8
)。当
1%2==1
时,将结果乘以6561,因为答案中有一个系数
3^8

public class maths 
{

    private float Base;
    private float Exponent;
    private float Modulus;
    private float Result;


    public float powermod(float base, float exponent, float modulus) 
    {
        if (base < 1 || exponent < 0 || modulus < 1)
        {
            return -1;
        }



        while (exponent > 0) 
        {
           if ((exponent % 2) == 1) 
           {
               Result = (Result * base) % modulus;
           }

        base = (base * base) % modulus;
        exponent = floor(exponent / 2);
        }
        return Result;
    } 


    public static void main(String[] args) {
        maths m = new maths();
       System.out.println( m.powermod(0, 1, 2));
       System.out.println( m.powermod(1, 2, 3));
        System.out.println(m.powermod(3, 3, 3));
        System.out.println(m.powermod(4, 4, 4));


    }

}
公共课数学
{
私人浮动基地;
私有浮动指数;
私有浮动模量;
私人浮动结果;
公共浮点powermod(浮点基数、浮点指数、浮点模数)
{
if(基<1 | |指数<0 | |模数<1)
{
返回-1;
}
而(指数>0)
{
如果((指数%2)==1)
{
结果=(结果*基础)%模数;
}
基底=(基底*基底)%模量;
指数=楼层(指数/2);
}
返回结果;
} 
公共静态void main(字符串[]args){
数学m=新数学();
System.out.println(m.powermod(0,1,2));
System.out.println(m.powermod(1,2,3));
System.out.println(m.powermod(3,3,3));
System.out.println(m.powermod(4,4,4));
}
}

假设您要计算x^y,y在Z中。注意y=y/2+y%2(使用“/”作为整数除法,使用“%”作为模数)

这样,仅使用整数除法和值的平方就可以计算任何指数

示例:x^19

1) 19%2==1 [rule c] => x^19=x'*(x'^9) where x' = x^2.
2) 9%2==1 [rule c] => x'^9=x''*(x''^4) where x'' = x'^2.
3) 4%2==0 [rule b] => x''^4=x'''^2 where x''' = x''^2.
4) 2%2==0 [rule b] => x'''^2 = x''''^1 where x''''=x'''^2.
5) x''''^1 [rule a] is immediate.
如果演算是在一个由整数mod n组成的有限域上进行的,那么逻辑是相同的

附录

事实上,同样的逻辑可以用于更简单的微积分和更容易理解的数字乘以整数的问题:x*y

a) if y == 0 then x*y=0; if y==1 then x*y=x; if y==-1 then x*y=-x.

b) If y%2 == 0 then x*y = (x*2)*(y/2) => multiply x by 2 (x'=x*2), divide y by two (y'=y/2), and apply recursively the algorithm to calculate x'*y' = x*y.

c) If y%2 == 1 then x*y = (x*2)+(x*2)*(y/2) => multiply x (x'=x*2), divide y by two (y'=y/2), apply recursively the algorithm to calculate x'*y', and after x*y = x'+x'*y'.

整数方式,乘积被简化为加法和移位运算。

这是一种通过对模运算进行平方运算的幂运算,即使用重复平方运算计算
base^指数mod mod
为什么指数有奇数检查?之所以有奇数检查,是因为指数可能不是偶数(正好可以被2整除),因此,剩余的应该被添加到额外的值中。它应该是
if(base<0n
为什么指数有奇数检查?这不是答案,只是OP不寻求的一个实现!感谢您的规则!
a) if y == 0 then x*y=0; if y==1 then x*y=x; if y==-1 then x*y=-x.

b) If y%2 == 0 then x*y = (x*2)*(y/2) => multiply x by 2 (x'=x*2), divide y by two (y'=y/2), and apply recursively the algorithm to calculate x'*y' = x*y.

c) If y%2 == 1 then x*y = (x*2)+(x*2)*(y/2) => multiply x (x'=x*2), divide y by two (y'=y/2), apply recursively the algorithm to calculate x'*y', and after x*y = x'+x'*y'.