Search code examples
c#decimalroundingdecimal-point

How to change the precision (with trailing zero preservation) for a decimal in C#


A decimal value in C# has a fixed decimal point and therefore knows how many decimal places it had when it was created:

25.000m.ToString()

returns "25.000", unlike a double which has a floating point.

This question is not about how to display a number with fixed decimals, I know the various string conversion options. This is about the internal representation of the decimal data type, I'm just using .ToString() to show it.

Now I want to round a number to a fixed number of decimals. This works:

Math.Round(25.0000m, 3) -> 25.000

But when the number of decimals was less than 3, or it comes from a double, it doesn't (of course):

Math.Round(25.00m, 3) -> 25.00
Math.Round((decimal) 25.0000d, 3) -> 25
(decimal) Math.Round(25.0000d, 3) -> 25

So how can I round any double number to a decimal with 3 forced places?

Since it's hard to explain, suggestions for a better title are welcome!


Solution

  • You could always add 0.000m onto the result:

            var x = Math.Round(25.00m, 3);
            var y = 0.000m;
            var z = x + y;
    

    Printing z shows it now has 3 decimal places. I agree with comments that this is of questionable value though.

    (NB - this still won't create 3 decimal places if the current value of x is sufficiently large that it cannot accommodate the additional places without changing the integral portion)


    EDIT by the questioner: To make this answer acceptable, adding this from the comments (the question asked for a double as source and this also solves an issue with VS2008):

    var z = Math.Round(((decimal) 25d) + 0.000m, 3);
    

    Interestingly in VS2008 it only works when the casting to decimal and adding 0.000m is done inside the Math.Round(). In VS2015 it can also be done outside. If anyone knows an explanation for this, please comment.