2011-09-20 16 views
12

Esiste una funzione incorporata che consenta di calcolare l'inverso modulare di una (mod n)? ad es. 19^-1 = 11 (mod 30), in questo caso il 19^-1 == -11 == 19;C# ModInverse Function

+0

Si noti che è possibile invertire moltiplicazioni arbitrari. Ad esempio 2 ha modulo 30 inverso moltiplicativo poiché GCD (2,30)! = 1 – CodesInChaos

risposta

0

Non c'è niente di integrato in C# per supportare l'aritmetica modulare. Devi implementarlo tu stesso, o meglio ancora, trovare una biblioteca.

+0

Che tipo di libreria? – Nook

+3

@Nook: er ... Una libreria C#? –

+0

Una libreria per l'aritmetica modulare. –

2

Il BouncyCastle libreria Crypto dispone di un'implementazione BigInteger che ha la maggior parte delle funzioni aritmetiche modulari. È nello spazio dei nomi Org.BouncyCastle.Math.

12

Dal .Net 4.0 + implementa BigInteger con una speciale aritmetica modulare funzionano ModPow (che produce “X potere Y modulo Z”), non hai bisogno di una libreria di terze parti di emulare ModInverse. Se n è un numero primo, tutto quello che dovete fare è quello di calcolare:

a_inverse = BigInteger.ModPow(a, n - 2, n) 

Per maggiori dettagli, guardare in Wikipedia: Modular multiplicative inverse, sezione Using Euler's theorem, il caso particolare “quando m è un numero primo”. A proposito, c'è un argomento SO più recente al riguardo: 1/BigInteger in c#, con lo stesso approccio suggested by CodesInChaos.

+5

Si noti che è il caso speciale, * quando m è un numero primo *. –

5
int modInverse(int a, int n) 
{ 
    int i = n, v = 0, d = 1; 
    while (a>0) { 
     int t = i/a, x = a; 
     a = i % x; 
     i = x; 
     x = d; 
     d = v - t*x; 
     v = x; 
    } 
    v %= n; 
    if (v<0) v = (v+n)%n; 
    return v; 
} 
+0

Sembra funzionare, ma sarebbe bello se potesse segnalare (ad esempio lanciando un'eccezione) se l'inverso è impossibile ('a' non è invertibile modulo' n') che accade quando 'a' e' n' condivide un fattore non banale (il loro GCD ne supera uno). –

1
BigInteger modInverse(BigInteger a, BigInteger n) 
     { 
      BigInteger i = n, v = 0, d = 1; 
      while (a > 0) 
      { 
       BigInteger t = i/a, x = a; 
       a = i % x; 
       i = x; 
       x = d; 
       d = v - t * x; 
       v = x; 
      } 
      v %= n; 
      if (v < 0) v = (v + n) % n; 
      return v; 
     } 
+4

Il downvoted per essere una copia (non formattata) della risposta Samuels con int sostituita da BigInteger. –