web-dev-qa-db-fra.com

Définissez la précision des nombres décimaux en C #

Est-il possible de changer la précision des nombres décimaux en C # globalement?

Dans TypeScript, j'utilise le framework Decimal.js , où je peux changer la précision des opérations Decimal globalement comme so Decimal.set({ precision: 15}). Cela signifie que l'opération renverra au plus 15 chiffres décimaux.

  • TypeScript : l'opération 5/3 résultats 1.66666666666667
  • C # l'opération5m/3m résultats 1.6666666666666666666666666667

Existe-t-il un paramètre similaire pour les valeurs décimales en C #? Comment puis-je accomplir cela en C #?

10
Devid

Ce n'est pas exactement ce que vous demandez, mais vous pouvez initialiser un objet NumberFormatInfo dans la portée globale et l'utiliser pour formater des décimales. Voici un exemple:

NumberFormatInfo setPrecision = new NumberFormatInfo();

setPrecision.NumberDecimalDigits = 2;

decimal test = 1.22223;

Console.Write(test.ToString("N", setPrecision)); //Should write 1.23

setPrecision.NumberDecimalDigits = 3;

test = 5m/3m;

Console.Write(test.ToString("N", setPrecision)); //Should write 1.667

Lien MSDN: https://msdn.Microsoft.com/en-us/library/system.globalization.numberformatinfo (v = vs.110) .aspx

Exemple d'utilisation de NumberDecimalDigits: https://msdn.Microsoft.com/en-us/library/system.globalization.numberformatinfo.numberdecimaldigits (v = vs.110) .aspx

11
Jacob Barnes

La documentation de Decimal.js indique ce qui suit:

précision

Le nombre maximum de chiffres significatifs du résultat d'une opération.

Toutes les fonctions qui renvoient un Decimal arrondiront la valeur de retour à des chiffres significatifs de précision à l'exception de Decimal, AbsoluteValue, Ceil, Floor, Negated, Round, toDecimalPlaces, toNearest et Truncated.

Eh bien, si vous avez vraiment besoin de ce comportement à l'échelle mondiale, alors implémentez simplement un type d'encapsuleur qui le fait, vous avez une bonne spécification à suivre:

public struct RoundedDecimal
{
    public static int Precision { get; private set; }

    public static Decimal AbsoluteValue(
        RoundedDecimal d) => Math.Abs(d.value);

    //same with ceiling, floor, etc.

    private readonly decimal value;

    public RoundedDecimal(decimal d)
    {
        value = Decimal.Round(d, Precision);
    }

    public static void SetPrecision(int precision)
    {
        Precision = precision; /*omitted argument validation*/ }

     public static implicit operator Decimal(
         RoundedDecimal d) => d.value;

    public static explicit operator RoundedDecimal(
        decimal d) => new RoundedDecimal(d);

    public static RoundedDecimal operator +(
        RoundedDecimal left, RoundedDecimal right) =>
           new RoundedDecimal(left.value + right.value);

    //etc.
}

En termes de performances, ce ne sera pas très impressionnant mais si c'est le comportement dont vous avez besoin , alors, par tous les moyens, implémentez-le!

AVERTISSEMENT: code écrit sur mon téléphone portable, donc il est lié à des bugs ... essayant simplement de faire passer l'idée.

6
InBetween

Il n'y a pas de paramètre générique pour la précision decimal. Votre meilleure chance est d'implémenter ces méthodes dans vos extensions.

var decimalValue = 5m/3m;
var str = decimalValue.ToString("0.##############");//1.66666666666667

ou vous pouvez utiliser Round;

var decimalValue = 5m/3m;
decimalValue = decimal.Round(decimalValue, 6, MidpointRounding.AwayFromZero);
6
lucky