1 / BigInteger en c #

Je veux faire

BigInteger.ModPow(1/BigInteger, 2,5); 

mais 1/BigInteger toujours 0 , ce qui fait que le résultat est également 0 . J’ai essayé de chercher une classe BigDecimal pour c # mais je n’ai rien trouvé. Est-il possible de compter cela même s’il n’y a pas de BigDecimal ?

1/a est 0 pour | a |> 1, puisque BigIntegers utilise une division entière où la partie fractionnaire d’une division est ignorée. Je ne sais pas quel résultat vous attendez pour cela.

Je suppose que vous voulez l’inverse multiplicatif modulaire d’ a modulo m , et non un nombre fractionnaire. Cet inverse existe si et aussi m et sont co-prime, c’est-à-dire gcd(a, m) = 1 .

La page wikipedia liée répertorie les deux algorithmes standard de calcul de l’inverse multiplicatif modulaire:

  • Algorithme euclidien étendu , qui fonctionne pour les modules arbitraires
    C’est rapide, mais son runtime dépend des entrées.

    Je n’ai pas de code C # sous la main, mais le pseudo-code de wikipedia devrait être facile à transférer.

  • En utilisant le théorème d’Euler:
    $ i ^ {- 1} = i ^ {φ (n) -1} $
    Cela nécessite la connaissance de φ (m), c’est-à-dire que vous devez connaître les facteurs premiers de m. C’est un choix populaire quand m est un nombre premier et donc φ (m) = m-1 quand il devient simplement $ a ^ {- 1} = a ^ {p-2} $ . Si vous avez besoin d’une durée d’exécution constante et que vous connaissez (m), c’est la voie à suivre.

    En C #, cela devient BigInteger.ModPow(a, phiOfM-1, m)

La surcharge de l’opérateur / choisi est la suivante:

 public static BigInteger operator /( BigInteger dividend, BigInteger divisor ) 

Voir Opérateur BigInteger.Division . Si le résultat est compris entre 0 et 1 (ce qui est probable lorsque le dividend est dividend 1 dans votre cas), étant donné que la valeur de retour est un entier, 0 est renvoyé, comme vous le voyez.

ModPow vous de faire avec la méthode ModPow ? Savez-vous que 2,5 sont deux arguments, deux et cinq, et non pas “deux points cinq”? Votre intention est-elle “prendre la place modulo 5”?

Si vous voulez une division en virgule flottante, vous pouvez utiliser:

 1.0 / (double)yourBigInt 

Notez le casting à double . Cela risque de perdre de la précision et même de ” yourBigInt ” à zéro si yourBigInt est trop énorme.

Par exemple, vous devez avoir d dans la prochaine:
3 * d = 1 (mod 9167368)

c’est également:
3 * d = 1 + k * 9167368, où k = 1, 2, 3, …

le réécrire:
d = (1 + k * 9167368) / 3

Votre d doit être l’entier avec le k le plus bas .
Écrivons la formule:
d = (1 + k * fi) / e

 public static int MultiplicativeInverse(int e, int fi) { double result; int k = 1; while (true) { result = (1 + (k * fi)) / (double) e; if ((Math.Round(result, 5) % 1) == 0) //integer { return (int)result; } else { k++; } } } 

testons ce code:

 Assert.AreEqual(Helper.MultiplicativeInverse(3, 9167368), 6111579); // passed