web-dev-qa-db-fra.com

Grands entiers en C #

Actuellement, je suis empruntant Java.math.BigInteger à partir des bibliothèques J # comme décrit ici . N'ayant jamais utilisé de bibliothèque pour travailler avec de grands nombres entiers auparavant, cela semble lent, de l'ordre de 10 fois plus lent, même pour les numéros de longueur ulong. Quelqu'un a-t-il de meilleures bibliothèques (de préférence gratuites), ou ce niveau de performance est-il normal?

64
Matthew Scharley

À partir de .NET 4.0, vous pouvez utiliser la classe System.Numerics.BigInteger. Voir la documentation ici: http://msdn.Microsoft.com/en-us/library/system.numerics.biginteger (v = vs.110) .aspx

Une autre alternative est la classe IntX .

IntX est une bibliothèque d'entiers de précision arbitraire écrite en C # 2.0 pur avec une implémentation rapide - O (N * log N) - d'algorithmes de multiplication/division. Il fournit toutes les opérations de base sur les entiers comme l'addition, la multiplication, la comparaison, le décalage au niveau du bit, etc.

64
Davorin

F# est également livré avec un. Vous pouvez l'obtenir sur Microsoft.FSharp.Math.

9
Steve Severance

Le System.Numerics.BigInteger classe dans .NET 4.0 est basée sur Microsoft.SolverFoundation.Common.BigInteger de Microsoft Research.

La classe BigInteger de la Solver Foundation semble très performante. Je ne suis pas sûr de la licence sous laquelle il est publié, mais vous pouvez l'obtenir ici (téléchargez et installez Solver Foundation et trouvez Microsoft.Solver.Foundation.dll).

8
Rasmus Faber

Je pense que vous pouvez optimiser l'implémentation si vous effectuez toutes les opérations sur BigInts qui vont retourner des résultats plus petits qu'un type natif (par exemple int64) sur les types natifs et ne traiter avec le grand tableau que si vous allez déborder.

edit Cette implémentation sur codeproject , semble seulement 7 fois plus lente ... Mais avec l'optimisation ci-dessus, vous pourriez la faire fonctionner presque identique aux types natifs pour les petits nombres.

4
Sam Saffron

Voici plusieurs implémentations de BigInteger en C #. J'ai utilisé l'implémentation BigInteger de Mono, fonctionne assez rapidement (je l'ai utilisé dans CompactFramework)

Château gonflable

Mono

4
Vadym Stetsiak

Je ne suis pas sûr des performances, mais IronPython a également une classe BigInteger. Il se trouve dans l'espace de noms Microsoft.Scripting.Math.

3
Daniel Plaisted

Oui, ce sera lent, et une différence de 10 fois correspond à ce à quoi je m'attendais. BigInt utilise un tableau pour représenter une longueur arbitraire, et toutes les opérations doivent être effectuées manuellement (contrairement à la plupart des mathématiques qui peuvent être effectuées directement avec le CPU)

Je ne sais même pas si le coder à la main dans Assembly vous donnera un gain de performances supérieur à 10x, c'est sacrément proche. Je chercherais d'autres façons de l'optimiser - parfois, en fonction de votre problème mathématique, vous pouvez faire de petites astuces pour le rendre plus rapide.

2
Bill K

J'ai utilisé Biginteger lors d'un travail précédent. Je ne sais pas quel type de performances vous avez besoin. Je ne l'ai pas utilisé dans une situation exigeante en performances, mais je n'ai jamais eu de problème avec.

2
Jason Jackson

Cela peut sembler une suggestion étrange, mais avez-vous testé le type décimal pour voir à quelle vitesse cela fonctionne?

La plage décimale est de ± 1,0 × 10 ^ −28 à ± 7,9 × 10 ^ 28, donc elle n'est peut-être pas encore assez grande, mais elle est plus grande qu'un ulong.

Il devait y avoir une classe BigInteger dans .NET 3.5, mais il a été coupé .

2
Powerlord

Voir les réponses dans ce thread . Vous devrez utiliser l'une des bibliothèques/classes de grands nombres entiers tiers disponibles ou attendre C # 4.0 qui inclura un type de données BigInteger natif.

1
Scott Dorman

Cela ne vous aidera pas, mais il devait y avoir une classe BigInteger dans .Net 3.5; il a été coupé, mais d'après les déclarations faites au PDC, il sera dans .Net 4.0. Apparemment, ils ont passé beaucoup de temps à l'optimiser, donc les performances devraient être bien meilleures que ce que vous obtenez maintenant.

De plus, cette question est essentiellement un doublon de Comment puis-je représenter un très grand entier dans .NET?

1
technophile

Cela semble très prometteur. Il s'agit d'un wrapper C # sur GMP .

http://web.rememberingemil.org/Projects/GnuMpDotNet/GnuMpDotNet.html

Il existe également d'autres options BigInteger pour .Net ici en particulier, Mpir.Net

1
Charles Okwuagwu

Vous pouvez également utiliser le package Nuget Math.Gmp.Native que j'ai écrit. Son code source est disponible sur GitHub , et la documentation est disponible ici . Il expose à .NET toutes les fonctionnalités de la bibliothèque GMP connue sous le nom de bibliothèque arithmétique de précision arbitraire hautement optimisée.

Les entiers de précision arbitraire sont représentés par le type mpz_t . Les opérations sur ces nombres entiers commencent toutes par le mpz_ préfixe. Par exemple, mpz_add ou mpz_cmp . Des exemples de code source sont donnés pour chaque opération.

0
RobertBaron