web-dev-qa-db-fra.com

Quel est l'équivalent de la classe Java BigDecimal en C #?

BigDecimal est une classe dans le Java.math package qui présente de nombreux avantages pour la gestion de grands nombres d'une certaine échelle. Existe-t-il une classe ou un type de données équivalent en c # avec cette fonctionnalité.

44
Radi

C # a uniquement été construit par BigInteger (dans .NET Framework 4).

decimal est-il suffisamment précis pour votre tâche? C'est un nombre de 128 bits qui peut contenir des valeurs dans la plage ± 1,0 × 10−28 à ± 7,9 × 1028.

28
Dean Harding

Tout récemment, j'avais également besoin d'une décimale de précision arbitraire en C # et je suis tombé sur l'idée publiée ici: https://stackoverflow.com/a/4524254/804614

J'ai ensuite terminé le projet pour prendre en charge tous les opérateurs arithmétiques et de comparaison de base, ainsi que les conversions vers et à partir de tous les types numériques typiques et quelques méthodes exponentielles, dont j'avais besoin à l'époque.

Ce n'est certainement pas complet, mais très fonctionnel et presque prêt à l'emploi. Comme c'est le résultat d'un codage d'une nuit, je ne peux pas garantir que cette chose est exempte de bogues ou entièrement exacte, mais cela a très bien fonctionné pour moi. Quoi qu'il en soit, je veux le publier ici parce que je n'ai trouvé aucun autre moyen d'utiliser des décimales de précision arbitraires en C # sans avoir besoin d'inclure des bibliothèques massives (surtout pas même .net, mais des wrappers en c ++), qui viennent avec toutes sortes d'inutiles des trucs.

L'idée de base est de créer un type à virgule flottante personnalisé avec une grande mantisse arbitraire en utilisant le type BigInteger de .NET 4.0 et un exposant de base 10 (Int32).

Si vous trouvez des bugs/inexactitudes, avez des suggestions ou quelque chose de constructif, n'hésitez pas à modifier directement mon message ou à laisser un commentaire afin que je puisse améliorer la réponse.

Je ne suis pas tout à fait sûr que ce soit le meilleur endroit pour placer cette chose, mais c'est l'une des principales questions sur SO sur ce sujet et je veux vraiment partager ma solution.;)

EDIT: J'ai déplacé l'implémentation vers GitHubGist: https://Gist.github.com/JcBernack/0b4eef59ca97ee931a2f45542b9ff06d

43
Gigo

Il existe une bibliothèque C # appelée BigNum qui fait ce que vous recherchez et, dans certains cas, a des fonctionnalités supplémentaires.

Par exemple, il a une fonction de racine carrée, que BigDecimal n'a pas:

PrecisionSpec precision = new PrecisionSpec(1024, PrecisionSpec.BaseType.BIN);
BigFloat bf = new BigFloat(13, precision);
bf.Sqrt();
Console.WriteLine(bf.ToString());

Wikipedia a une liste d'autres bibliothèques de ce type sur http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic#Libraries

Sources:

4
RedGreenCode

Eh bien, à part l'utilisation de bibliothèques tierces avec le support de BigDecimal (si elles existent), il n'y a pas de solution de contournement facile. Pour moi, le plus simple est de prendre une implémentation décimale (de mono par exemple) et de la réécrire en utilisant le type BigInteger. En interne, dans l'implémentation de mono, le type décimal est composé de trois entiers. Je ne pense donc pas que ce serait difficile à mettre en œuvre. Je ne suis cependant pas sûr de l'efficacité. Cependant, vous devez d'abord envisager d'utiliser le type décimal standard comme codeka mentionné.

4
n535

Cela n'était peut-être pas une option lorsque la question a été initialement publiée, mais un moyen très simple d'utiliser un BigDecimal dans votre code C # consiste à installer le package IKVM.NET via NuGet:

PM> Install-Package IKVM

Ensuite, faites exactement comme vous le feriez en Java:

using System;
using Java.math;

namespace BigDecimalDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = int.Parse(args[0]);
            Console.WriteLine(Factorial(n));
        }

        static BigDecimal Factorial(int n)
        {
            return n == 1
                ? BigDecimal.ONE
                : Factorial(n - 1).multiply(new BigDecimal(n));
        }
    }
}

Selon jusqu'où vous allez avec IKVM, il peut y avoir un problème d'interopérabilité occasionnel, mais d'après mon expérience, cela fonctionne généralement très bien pour des choses simples comme celle-ci.

2
toddprater

Deveel Math

GitHub:

https://github.com/deveel/deveel-math

Auteur GitHub:

Antonello Provenzano

Soutien:

  • BigComplex
  • BigDecimal
  • BigMath
  • Rationnel
  • ...

Comment l'installer

Dans la console NuGet Package Management, sélectionnez le projet dans lequel la bibliothèque sera installée et tapez la commande suivante

PM> Install-Package dmath
1
TUPUNCO

Vous pouvez également utiliser le package Math.Gmp.Native NuGet 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 nombres à virgule flottante de précision arbitraire sont représentés par le type mpf_t . Les opérations sur ces nombres à virgule flottante commencent toutes par le mpf_ préfixe. Par exemple, mpf_add ou mpf_cmp . Des exemples de code source sont donnés pour chaque opération.

0
RobertBaron