feat: add modular inv
This commit is contained in:
63
src/main/java/me/hatter/math/ModularInv.java
Normal file
63
src/main/java/me/hatter/math/ModularInv.java
Normal file
@@ -0,0 +1,63 @@
|
||||
package me.hatter.math;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
|
||||
// https://zhuanlan.zhihu.com/p/426499159
|
||||
// def modular_inv(a, p):
|
||||
// x, y, m = 1, 0, p
|
||||
// while a > 1:
|
||||
// q = a // m
|
||||
// t = m
|
||||
//
|
||||
// m = np.mod(a, m)
|
||||
// a = t
|
||||
// t = y
|
||||
//
|
||||
// y, x = x - np.int64(q) * np.int64(y), t
|
||||
//
|
||||
// if x < 0:
|
||||
// x = np.mod(x, p)
|
||||
// return np.mod(x, p)
|
||||
public class ModularInv {
|
||||
|
||||
public static void main(String[] args) {
|
||||
for (long i = 1; i < 10000; i++) {
|
||||
for (long j = 1; j < 10000; j++) {
|
||||
BigInteger a = BigInteger.valueOf(i);
|
||||
BigInteger p = BigInteger.valueOf(j);
|
||||
if (!a.gcd(p).equals(BigInteger.ONE)) {
|
||||
continue;
|
||||
}
|
||||
BigInteger x = a.modInverse(p);
|
||||
BigInteger y = modularInv(a, p);
|
||||
System.out.println(Arrays.asList(a, p, a.modInverse(p), modularInv(a, p)));
|
||||
if (!y.equals(x)) {
|
||||
throw new RuntimeException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static BigInteger modularInv(BigInteger a, BigInteger p) {
|
||||
BigInteger x = BigInteger.ONE;
|
||||
BigInteger y = BigInteger.ZERO;
|
||||
BigInteger m = p;
|
||||
while (a.compareTo(BigInteger.ONE) > 0) {
|
||||
BigInteger q = a.divide(m);
|
||||
BigInteger t = m;
|
||||
|
||||
m = a.mod(m);
|
||||
a = t;
|
||||
t = y;
|
||||
|
||||
y = x.subtract(q.multiply(y));
|
||||
x = t;
|
||||
|
||||
if (x.compareTo(BigInteger.ZERO) < 0) {
|
||||
x = x.mod(p);
|
||||
}
|
||||
}
|
||||
return x.mod(p);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user