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);
}
}
}
这是我编写的java程序,用于计算乘法模数逆(模10 ^ 9 + 7)。但它给出负数作为大于10的数字的输出。 无法弄清楚出了什么问题。
答案 0 :(得分:1)
But it gives negative numbers as output for numbers greater than 10
那是因为你已经达到positive overflow
长,因此返回/从负溢出开始。
很长,当您到达minimum value of -2^63 and a maximum value of 2^63-1
时,此值的范围为2^63-1
,然后返回-2^63
并从那里开始。
答案 1 :(得分:1)
我在底部的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
现在846153852×846153852×13> 2 63 ,因此您的代码溢出了Java long
的范围。
mod
是10 9 + 7,如果result
介于0和mod
之间,则result * result
将不会更多超过10 18 ,当然小于1.1×10 18 。 a long
可以容纳的最大正值约为9.2×10 18 ,因此一旦n
超过9,result * result * n
就有可能超过n = 13
这个价值。据我所知,这首先发生在mod
。
模数为long
的两个数字的乘积将永远不会超出Java return (((n % mod) * (result * result)) % mod);
的范围,但可能包含三个或更多数字的乘积。
解决此问题的一种方法是更换行
return (((n % mod) * ((result * result) % mod) % mod);
与
{{1}}