ある基底 b を p 乗し、そのモジュロ m をとります。
b=55170 または 55172 で、m=3043839241 (たまたま 55171 の 2 乗) とします。linux-calculatorbc
は結果を返します (制御のためにこれが必要です):
echo "p=5606;b=55171;m=b*b;((b-1)^p)%m;((b+1)^p)%m" | bc
2734550616
309288627
55170^5606 を計算すると、やや大きな数値が得られますが、剰余演算を行う必要があるため、次の理由により、BigInt の使用を回避できると考えました。
(a*b) % c == ((a%c) * (b%c))%c i.e.
(9*7) % 5 == ((9%5) * (7%5))%5 =>
63 % 5 == (4 * 2) %5 =>
3 == 8 % 5
... そして a^d = a^(b+c) = a^b * a^c なので、b+c を 2 で割り、偶数または奇数の ds に対して d/2 および d-(d /2)、したがって 8^5 の場合、8^2 * 8^3 を計算できます。
したがって、その場で除数を常にカットする私の(欠陥のある)方法は次のようになります。
def powMod (b: Long, pot: Int, mod: Long) : Long = {
if (pot == 1) b % mod else {
val pot2 = pot/2
val pm1 = powMod (b, pot2, mod)
val pm2 = powMod (b, pot-pot2, mod)
(pm1 * pm2) % mod
}
}
いくつかの値を与えられ、
powMod (55170, 5606, 3043839241L)
res2: Long = 1885539617
powMod (55172, 5606, 3043839241L)
res4: Long = 309288627
ご覧のとおり、2 番目の結果は上記の結果とまったく同じですが、最初の結果は静かに異なって見えます。私はそのような計算をたくさん行っており、Int の範囲内にある限り正確に見えますが、エラーは見られません。BigInt の使用も同様に機能しますが、遅すぎます。
def calc2 (n: Int, pri: Long) = {
val p: BigInt = pri
val p3 = p * p
val p1 = (p-1).pow (n) % (p3)
val p2 = (p+1).pow (n) % (p3)
print ("p1: " + p1 + " p2: " + p2)
}
calc2 (5606, 55171)
p1: 2734550616 p2: 309288627
(bc と同じ結果) 誰かがエラーを確認できますかpowMod
?