[英]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 aBigInteger
whose value is (this
^exponent
modm
).public BigInteger modPow(BigInteger exponent, BigInteger m)
-返回一个BigInteger
其值为(this
^exponent
modm
)。 (Unlikepow
, 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 % m
和b' = b % m
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.