[英]computing (a^b)%m in java
在尝试实现Miller-Rabin素数测试时,我遇到了Java的奇怪行为。 关于以下代码:
long x = (long) (Math.pow(a, b));
对于足够大(不需要那么多)的a和b,您将始终得到x = 9223372036854754775807 = Long.MAX_VALUE
而不是溢出值。
这个结果是完全没有用的,也无助于计算(a ^ b)%m,这是我们所需要的。
现在,由于(a ^ b)%m可以轻松地容纳(a ^ b)的64位,所以我想知道是否存在一种无需使用BigInteger
即可计算此数字的方法吗?
使用BigInteger
,尤其是方法modPow()
。 从javadocs:
public BigInteger modPow(BigInteger exponent, BigInteger m)
-返回一个BigInteger
其值为(this
^exponent
modm
)。 (与pow
不同,此方法允许使用负指数。)
例如:
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
您总是可以自己实现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
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.