import java.util.*;
class ModuloInverse {
static long mod = 1000000007;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
long num = in.nextLong();
System.out.println(m_inverse(num, mod));
}
static long m_inverse(long a, long p) {
return m_pow(a, p - 2);
}
static long m_pow(long n, long m) {
long result = 0;
if (m == 1) {
return (n % mod);
}
if (m % 2 == 0) {
result = m_pow(n, m / 2);
return ((result * result) % mod);
} else {
result = m_pow(n, (m - 1) / 2);
return (((n % mod) * (result * result)) % mod);
}
}
}
这是我编写的用于计算乘法模逆(模 10^9+7)的 java 程序。但对于大于 10 的数字,它给出负数作为输出。 无法弄清楚出了什么问题。
最佳答案
我在底部的 if
语句中添加了几行调试行:
if (m % 2 == 0) {
result = m_pow(n, m / 2);
System.out.println("m = " + m + ", result = " + result + ", returning " + ((result * result) % mod));
return ((result * result) % mod);
} else {
result = m_pow(n, (m - 1) / 2);
System.out.println("m = " + m + ", n % mod = " + (n % mod) + ", result = " + result + ", returning " + (((n % mod) * (result * result)) % mod));
return (((n % mod) * (result * result)) % mod);
}
当我使用值 13 运行此命令时,这是打印出来的最后一行:
m = 1000000005, n % mod = 13, result = 846153852, returning -428497853
Now 846153852 × 846153852 × 13 > 263, so your code is overflowing the range of a Java long
.
mod
is 109 + 7, and if result
is between 0 and mod
, then result * result
won't be much more than 1018, certainly less than 1.1 × 1018. The maximum positive value a long
can hold is about 9.2 × 1018, so once n
creeps above about 9, there is the chance that result * result * n
will exceed this value. As far as I can see, this first happens with n = 13
.
The product of two numbers modulo mod
will never exceed the range of a Java long
, but the product of three or more numbers might do.
One way to fix this is by replacing the line
return (((n % mod) * (result * result)) % mod);
与
return (((n % mod) * ((result * result) % mod) % mod);
关于用于计算模逆的 Java 程序输出大于 10 的数字的负值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25125132/