Java模块乘法逆

时间:2016-09-11 16:00:17

标签: java

我不能为我的生活弄清楚如何找到模块乘法逆模5.我已阅读所有维基文章,观看视频,甚至寻找同学的帮助,无法找到解决方案。我发现的一切都是在另一种编程语言中我无法转换为Java(新编程)和/或使用双精度而不是整数,我只能根据教授的规格使用整数。这是我到目前为止所编写的类,在我找出divide()方法之前无法执行inverse()方法:

public class ModInt {

    /**
     * the integer modulo base
     */
    private int base;

    /**
    *  the number
    */
    private int number;

    /**
     * creates the modulo 2 number 0
     */
    public ModInt()
    {
        base = 2;
        number = 0;
    }

    /**
     * creates a modulo b number n
     * @param n the number
     * @param b the base
     */
    public ModInt(int n, int b)
    {
       number = n;
       base = b;
    }

    /**
     * creates an equivalent number in the same integer modulo base as the specified integer modulo number.
     * @param m an integer modulo number
     */
    public ModInt(ModInt m)
    {
       number = m.number;
       base = m.base;
    }

    /**
     * gives the number of the integer modulo number.
     * @return the number
     */
    public int getNumber()
    {
        return number;
    }

    /**
     * gives the base of the specified integer modulo number.
     * @return the base
     */
    public int getBase()
    {
        return base;
    }

    /**
     * modifies the integer modulo number using the specified parameters
     * @param n the new number
     * @param b the new base
     */
    public void setModInt(int n, int b)
    {
       number = n;
       base = b;
    }

    /**
     * adds this integer modulo number and the specified integer modulo number
     * @param m an integer modulo number
     * @return the sum of this number and the specified number
     */
    public ModInt add(ModInt m)
    {
       return new ModInt((number + m.number) % base, base);     
    }

    /**
     * subtracts this integer modulo number and the specified integer modulo number
     * @param m an integer modulo number
     * @return the difference this number and the specified number
     */
    public ModInt subtract(ModInt m)
    {
        return new ModInt(((base - number + m.number) % base, base);
    }

    /**
     * multiplies this integer modulo number and the specified integer modulo number
     * @param m an integer modulo number
     * @return the product of this number and the specified number
     */
    public ModInt multiply(ModInt m)
    {
       return new ModInt((number * m.number) % base, base);
    }    

    /**
     * computes the inverse of this integer modulo number
     * @return the inverse of this number
     */
    public ModInt inverse()
    {
       return new ModInt();
    }

    /**
     * divides this integer modulo number and the specified integer modulo number
     * @param m an integer modulo number
     * @return the quotient of this number and the specified number
     */
    public ModInt divide(ModInt m)
    {
       return new ModInt();
    }    

    /**
     * give the string representation of an integer modulo number in the format
     * n(mod b), where n is the number and b is the base
     * @return a string representation of the integer modulo number in the format
     * n(mod b); for example 3(mod 5) is the representation of the number 
     * 3 in integer modulo base 5
     */
    public String toString()
    {
       return String.format("%d(mod %d)", number, base);
    }

}

我正在尝试编写inverse()方法,因此它返回整数模数(mod 5)的倒数。现在,我让它只返回默认构造函数,以便在运行代码时错误消失。任何人都可以尝试使用ONLY整数类型,没有双打或任何其他类型来解释如何找到模乘法逆?这是我教授对它的解释,但我不明白:

  

乘法逆或简单数n的倒数,   表示为n ^( - 1),在整数模数b中,是一个数字   乘以n与1一致;即,n×n ^( - 1)≡1(mod b)。对于   例如,5 ^( - 1)整数模7是3,因为(5×3)mod 7 = 15 mod7≡1。   数字0没有反转。并非每个数字都是可逆的。对于   例如,2 ^( - 1)整数模4是不确定的,因为{0中没有整数,   1,2,3}可以乘以2得到1。

感谢任何帮助,谢谢。

3 个答案:

答案 0 :(得分:0)

我从https://comeoncodeon.wordpress.com/2011/10/09/modular-multiplicative-inverse/获取了强力算法,它在C ++中,但几乎编译为Java。所以我的大部分工作都是根据你的班级来定制它。这是结果:

/**
 * computes the inverse of this integer modulo number
 * 
 * @return the inverse of this number
 */
public ModInt inverse() {
    int a = number % base;
    for (int x = 1; x < base; x++) {
        if ((a * x) % base == 1) {
            return new ModInt(x, base);
        }
    }
    throw new ArithmeticException("No inverse of " + toString());
}

答案 1 :(得分:0)

这应该做到。如果am不是相对质数(即具有一个非1的公约数),则将返回-1

如果从gcd1 to m的互斥程度较低,则在从a进行迭代之前,我包括了对m方法的调用,以使过程短路。


     public static int mod(int a, int m) {
        if (gcd(a,m) != 1) {
            return -1;
        }
        int x;
        for (x = 1; x < m; x++) {
            if ((a * x) % m == 1) {
                break;
            }
        }
        return x;
    }
    public static int gcd(int r, int s) {
        while (s != 0) {
           int t = s;
           s = r % s;
           r = t;
        }
        return r;
    }

有关更多信息,请查看Modular Multiplicative Inverse

答案 2 :(得分:0)

在进行乘法逆运算之前,先了解一些事实。

给定方程:

enter image description here

<块引用>

具有 a 的乘法倒数当且仅当 n>1 , gcd(a,n) = 1. and b =1

因此等式变为:

enter image description here

<块引用>

其中 a^{-1} 是 a 的乘法倒数。

使用扩展的Eculid算法给定两个整数a,b; gcd(a,b) 可以写成 a 和 b 的线性组合,所以方程变为:

enter image description here

我们需要找到 x 的值,它是 a 的乘法倒数。

如果 x 的值为负,则使用以下模算术的性质加上 n 使其为正。

enter image description here

这是执行相同操作的 java 代码:

import java.math.BigInteger;

public class ExtendedEculid {

    public static int[] egcd(int a, int b) {
        if (b == 0)
            return new int[] { a, 1, 0 };
        else {
            int[] arr = egcd(b, a % b);

            int gcd = arr[0];
            int X = arr[2];
            int Y = arr[1] - (a / b) * arr[2];

            return new int[] { gcd, X, Y };
        }
    }

    public static int multiplicativeInverse(int a, int modulo) {

        int[] egcdValues = egcd(a, modulo);

        // since multiplicative inverse exist iff gcd(a,modulo) =1
        // if no inverse exist then return 0

        if (egcdValues[0] != 1)
            return 0;
        if (egcdValues[1] > 0)
            return egcdValues[1];
        else
            return egcdValues[1] + modulo;
    }
    
    
    public static void main(String[] args) {
        
        System.out.println(multiplicativeInverse(5, 7));
        
        // using BigInteger
        BigInteger a = new BigInteger("5");
        BigInteger m = new BigInteger("7");
        System.out.println(a.modInverse(m));
        
    }
}

编辑:java.math.BigInteger 有一个方法 modInverse here。您也可以使用它,为它添加了代码片段。

参考资料:CLRS,算法简介,第 3 版,第 31 章