[英]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.