Java BigInteger,数论,模运算

时间:2014-12-19 01:26:49

标签: java biginteger number-theory modular-arithmetic

任何人都知道如何在java中实现这样的问题?

“实现一个带有三个正整数参数(a; b; n)的子程序并返回 值的((a到b的幂)mod n),其中参数由大约100个十进制数字表示。使用四种不同的方法。“

提前致谢

UPD:方法如下

M1)

public BigInteger Result1(BigInteger a , BigInteger b , BigInteger n){
    BigInteger Res = new BigInteger("1");
    for (BigInteger i = new BigInteger("0"); !i.equals(b); i = i.add(new BigInteger("1"))) {
        Res = Res.multiply(a).mod(n);
    }
    return Res;
}

M2)

public BigInteger Result2(BigInteger a , BigInteger b , BigInteger n){
    BigInteger Res = new BigInteger("1");
    for (BigInteger i = new BigInteger("0"); !i.equals(b); i = i.add(new BigInteger("1"))) {
        Res = Res.multiply(a);
    }
    return Res.mod(n);
}

M3)

ublic BigInteger Result3(BigInteger a , BigInteger b , BigInteger n){
    if(b.equals(new BigInteger("0"))){
        return new BigInteger("1");
    }
    else if(b.mod(new BigInteger("2")).equals(new BigInteger("0"))){
        BigInteger Res = Result3(a,b.divide(new BigInteger("2")),n);
        return (Res.multiply(Res)).mod(n);
    }
    else{
        return ( (a.mod(n)).multiply(Result3(a, b.subtract(new BigInteger("1")), n)) ).mod(n);
    }
}

M4)

public BigInteger Result4(BigInteger a , BigInteger b , BigInteger n){
    BigInteger Res = new BigInteger("1");
    while(!b.equals(new BigInteger("0"))) {
        if(!(b.mod(new BigInteger("2"))).equals(new BigInteger("0"))) {
            Res = Res.multiply(a).mod(n);
        }
        a = a.multiply(a).mod(n);
        b = b.divide(new BigInteger("2"));
    }
    return Res;
}

3 个答案:

答案 0 :(得分:1)

直接回答你的问题, 我认为BigInteger.modPow可能是你正在寻找的东西。

public BigInteger modPow(BigInteger exponent,
                     BigInteger m)

返回一个BigInteger,其值为(this ^ exponent mod m)

或者(并且更有效率),你也可以((mod n)获得(b mod n)幂,这应该使代码运行得更快。

(a ^ b mod n)=((mod n)^(b mod n)mod n)

答案 1 :(得分:0)

如果您不是非常需要表现,可以使用BigInteger课程。 BigInteger是不可变的。

public static BigInteger getValue(int a, int b, int n) {
    return BigInteger.valueOf(a).modPow(BigInteger.valueOf(b), BigInteger.valueOf(n));
}

答案 2 :(得分:0)

慌张,这被搁置......

为了理论,如果你想编写自己的自定义方法,请根据数学技巧检查以下内容,以避免计算。首先是解决方案,然后是背后的数学。

您的子程序可能如下所示:

public static BigInteger customPowMod(BigInteger a, BigInteger b, BigInteger n){
    BigInteger previous = a.mod(n);
    BigInteger runningTotal = new BigInteger("1");
    for(int i = 0; i < a.bitLength(); i++){
        if(a.testBit(i)){
            runningTotal = runningTotal.multiply(previous);
        }
        previous = previous.multiply(previous).mod(n);
    }
    return runningTotal.mod(n);
}

以下是如何调用该方法的示例:

public static void main(String[] args) {
    BigInteger a = new BigInteger("1700000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005");
    BigInteger b = new BigInteger("6300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005");
    BigInteger n = new BigInteger("50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000");
    //note the following produce the same values
    System.out.println(customPowMod(a,b,n)); 
    System.out.println(a.modPow(b,n));
}

现在解释

为了解释事情,我正在做较小的数字...这是手工过程,最后变成了代码。

  • a = 17
  • b = 63
  • n = 5

首先您希望了解您的电源号b由哪个base2供电。例如:

  

63 = 2 ^ 5 + 2 ^ 4 + 2 ^ 3 + 2 ^ 2 + 2 ^ 1 + 2 ^ 0 = 32 + 16 + 8 + 4 + 2 + 1.

OR二进制 11111

这可以通过从0迭代到我们的BigInteger b的.bitLength()并用.testBit()检查给定位来以编程方式找到。 因此Java代码中的for循环。

下一步我们会找到您的基本模数(n)目标的倍数(您需要的值远远超过前一段的最高2):

让我们调用每个简化值a<power_of_2>

  • a mod n = a1
  • a ^ 2 mod n = a2
  • a ^ 4 mod n =(a2)^ 2 mod n = a4 mod n
  • a ^ 8 mod n =(a4)^ 2 mod n = a8 mod n
  • ...

和手工值:

  • 17 ^ 1 %5 = 2
  • 17 ^ 2 %5 = 2 ^ 2 mod 5 = 4 mod 5 = 4
  • 17 ^ 4 %5 = 4 ^ 2 mod 5 = 16 mod 5 = 1
  • 17 ^ 8 %5 = 1 ^ 2 mod 5 = 1 mod 5 = 1
  • 17 ^ 16 %5 = 1 ^ 2 mod 5 = 1 mod 5 = 1
  • 17 ^ 32 %5 = 1 ^ 2 mod 5 = 1 mod 5 = 1

问题是这可以与找到base2权限的上一步同步完成,每次迭代你也会找到最新的a<power_of_2>需要计算每个额外的方块,直到我们达到最大值,因此循环中的previous值不断增加。

最后,我们将必要的值与彼此相加,然后是n的模数。 这是在foor-loop的if语句中。

  • 同样,我们有权力: 32 + 16 + 8 + 4 + 2 + 1

从上面的步骤我们得到了值并将它们加在一起(后跟循环结束时的模数):

  

1 * 1 * 1 * 1 * 4 * 2 %5 = 8%5 = 3