在尝试实现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
的情况下计算该数字?
答案 0 :(得分:1)
使用BigInteger
,尤其是方法modPow()
。来自javadocs:
public BigInteger modPow(BigInteger exponent, BigInteger m)
-返回值为{BigInteger
^this
modexponent
的{{1}}。 (与m
不同,此方法允许使用负指数。)
例如:
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 % m
和b' = b % m
。