模乘乘法反函数不适用于负数

时间:2014-10-01 15:30:14

标签: c++ modulo inverse

我有下面的函数来计算给定模数p的数n的模乘法逆。

int modInverse(int n, int p) {
    n %= p;
    for(int x = 1; x < p; x++) {
        if((n*x) % p == 1) return x;
    }
}

如果n是正数,那就很好,但如果n是负数,它总是为0。 我该如何解决?

x mod n的乘法逆:x ^ -1 mod n,是必须乘以x得到1 mod n的数字 例如3 ^ -1 mod 7 = 5,因为3 * 5 = 1 mod 7

2 个答案:

答案 0 :(得分:2)

示例代码:

int modulo(int n, int p)
{
int r = n%p;
    if(((p > 0) && (r < 0)) || ((p < 0) && (r > 0)))
        r += p;
    return r;
}

int modInverse(int n, int p) {
    n = modulo(n, p);
    for(int x = 1; x < p; x++) {
        if(modulo(n*x, p) == 1) return x;
    }
    return 0;
}

int main(void)
{
int r;
    r = modInverse(-25, 7);
    return 0;
}

如果你想要商和余数:

void divmod(int n, int p, int &q, int &r)
{
    q = n/p;
    r = n%p;
    if(((p > 0) && (r < 0)) || ((p < 0) && (r > 0))){
        q -= 1;
        r += p;
    }
}

答案 1 :(得分:0)

除了不必要的迭代之外,您使用的方法具有O(p)复杂度。您可能希望使用O(log(p))复杂度的扩展欧几里得算法。无论如何,回答你的问题和你做的方式,我建议你尝试这种方法,这减少了迭代次数:( Java)

int calculateInverse2(int a, int zp) {
    for (int i = (int) Math.ceil((zp-1)/a); i < zp; i++) {
        if (Math.floorMod(a*i,zp) == 1) return i;
    }
    return -1;
}

与模运算中的负值相关,取决于语言。尝试实现一种方法,该方法将某些时间p相加以在整数环内建立数字。

示例:

(-7)mod(2) => (-7+2)mod(2) => (-7+2+2)mod(2) => (-7+2+2+2)mod(6) => (-7+2+2+2+2)mod(6) => (1)mod(7)=1

易于计算。