简体   繁体   English

在Java中计算(a ^ b)%m

[英]computing (a^b)%m in java

While trying to implement the Miller-Rabin primality test I came across a strange behaviour of java. 在尝试实现Miller-Rabin素数测试时,我遇到了Java的奇怪行为。 Regard the following code: 关于以下代码:
long x = (long) (Math.pow(a, b));
For a and b large enough (doesn't need that much) you will always get x = 9223372036854775807 = Long.MAX_VALUE instead of an overflow value. 对于足够大(不需要那么多)的a和b,您将始终得到x = 9223372036854754775807 = Long.MAX_VALUE而不是溢出值。
This result is completely useless and won't help calculating (a^b)%m, which is what we need. 这个结果是完全没有用的,也无助于计算(a ^ b)%m,这是我们所需要的。
Now since (a^b)%m would easily fit into 64 bits when (a^b) doesn't, I wonder if there is a way to calculate this number without using BigInteger ? 现在,由于(a ^ b)%m可以轻松地容纳(a ^ b)的64位,所以我想知道是否存在一种无需使用BigInteger即可计算此数字的方法吗?

Use BigInteger , in particular the method modPow() . 使用BigInteger ,尤其是方法modPow() From the javadocs: 从javadocs:

public BigInteger modPow(BigInteger exponent, BigInteger m) - Returns a BigInteger whose value is ( this ^ exponent mod m ). public BigInteger modPow(BigInteger exponent, BigInteger m) -返回一个BigInteger其值为( this ^ exponent mod m )。 (Unlike pow , this method permits negative exponents.) (与pow不同,此方法允许使用负指数。)

https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html#modPow(java.math.BigInteger,%20java.math.BigInteger) https://docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html#modPow(java.math.BigInteger,%20java.math.BigInteger)

For Example: 例如:

BigInteger a = BigInteger.valueOf(2);
BigInteger b = BigInteger.valueOf(3);
BigInteger m = BigInteger.valueOf(7);

BigInteger result = a.modPow(b, m);  // i.e. 2 ^ 3 mod 7 -> 8 mod 7 -> 1
System.out.println(result);  // prints 1

You can always implement the pow(...) yourself and mod as often as possible. 您总是可以自己实现pow(...),并尽可能经常地对其进行修改。 Generally speaking (in pseudo-code): 一般来说(用伪代码):

powMod(a, b, m) {
    result = 1
    for (i = 0; i < b; i++) {
        result = (result * a) % m
    }
    return result
}

If result * a may be too large then you may want to implement * by repeated addition and modding after each + . 如果result * a可能太大,那么您可能希望通过在+之后重复添加和修改来实现* Furthermore you can (and should) always use a' = a % m and b' = b % m if you don't do that already. 此外,如果您尚未这样做,则可以(并且应该)始终使用a' = a % mb' = b % m

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM