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,结果 = 846153852,返回 -428497853
现在846153852 × 846153852 × 13> 263,因此您的代码超出了 Java long
的范围。
mod
是 109 + 7,如果result
介于 0 和 mod
之间,那么result * result
不会超过 10 18,肯定小于 1.1 × 1018。 long
可以保持的最大正值约为 9.2 × 1018,因此一旦n
爬升到约 9 以上,result * result * n
就有可能超过该值。 据我所知,这首先发生在n = 13
.
两个数的乘积模mod
永远不会超过Java long
的范围,但三个或更多数的乘积可能会超过。
解决此问题的一种方法是更换行
return (((n % mod) * (result * result)) % mod);
跟
return (((n % mod) * ((result * result) % mod) % mod);
But it gives negative numbers as output for numbers greater than 10
那是因为你已经到了多头的positive overflow
,因此回到/从负溢出开始。
Long 的这个值的范围从 minimum value of -2^63 and a maximum value of 2^63-1
到你达到2^63-1
然后它会回到-2^63
并从那里开始。