用于计算模逆的 Java 程序输出大于 10 的数字的负值

标签 java modular-arithmetic

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/

相关文章:

java - 文件异常错误

java - 无法通过此 java 代码的输出找到答案

java - 使用 Node.js Express 从改造中提取 @Field 参数

haskell - Haskell 中的模方程

maple - FEA 程序密码学

isabelle - 证明关于 case mod 10 的简单定理

java - 使用 Intent 传递整数在 Android 中不起作用

java - 根据从不同类别获得的值更新进度条

gmp - Mathematica PowerMod inverse 和 C 语言中的 mpz_powm

algorithm - 在多个处理器上进行大整数模乘的最快运行时间是多少?