简体   繁体   中英

Set the precision for Decimal numbers in C#

Is it possible to change the precision for Decimal numbers in C# globally ?

In TypeScript I am using the framework Decimal.js , where I can change the precision of the Decimal operations globally like so Decimal.set({ precision: 15}) . This means that the operation will return at most 15 decimal digits.

  • TypeScript :the operation 5/3 returns 1.66666666666667
  • C# the operation 5m/3m returns 1.6666666666666666666666666667

Is there some similar setting for Decimal values in C# ? How can I accomplish this in C# ?

This isn't exactly what you're asking, but you could initialize a NumberFormatInfo object within the global scope and use it to format decimals. Here is an example:

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

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

NumberDecimalDigits usage example: https://msdn.microsoft.com/en-us/library/system.globalization.numberformatinfo.numberdecimaldigits(v=vs.110).aspx

There is no generic setting for decimal precision. Your best chance is implementing these methods in your extensions.

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

or you could use Round ;

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

The documentation of Decimal.js states the following:

precision

The maximum number of significant digits of the result of an operation.

All functions which return a Decimal will round the return value to precision significant digits except Decimal, absoluteValue, ceil, floor, negated, round, toDecimalPlaces, toNearest and truncated.

Well, if you really need that behavior globally, then simply implement a wrapper type that does that, you've got a good specification to go by:

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.
}

Performance wise this will not be very impressive but if its the behavior you need then, by all means, implement it!

DISCLAIMER: written code on my cell phone, so its bound to have bugs... simpy trying to get the idea across.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM