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

时间:2019-08-14 14:09:28

标签: java math long-integer

在尝试实现Miller-Rabin primality test时,我遇到了Java的奇怪行为。关于以下代码:
long x = (long) (Math.pow(a, b));
对于足够大的a和b(不需要那么多),您将始终得到x = 9223372036854754775807 = Long.MAX_VALUE而不是溢出值。
此结果完全没有用,也无助于计算我们需要的(a ^ b)%m。
现在由于(a ^ b)不适合(a ^ b)%m时,它很容易适合64位,我想知道是否有一种方法可以在不使用BigInteger的情况下计算该数字?

2 个答案:

答案 0 :(得分:1)

使用BigInteger,尤其是方法modPow()。来自javadocs:

  

public BigInteger modPow(BigInteger exponent, BigInteger m)-返回值为{BigInteger ^ this mod exponent的{​​{1}}。 (与m不同,此方法允许使用负指数。)

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

例如:

pow

答案 1 :(得分:1)

您始终可以自己实现pow(...),并尽可能经常地对其进行调制。一般来说(用伪代码):

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

如果result * a太大,那么您可能想通过在每个*之后重复添加和修改来实现+。此外,如果您尚未这样做,则可以(并且应该)始终使用a' = a % mb' = b % m