views:

839

answers:

5

How can I format a number to a fixed number of decimal places (keep trailing zeroes) where the number of places is specified by a variable?

e.g.

int x = 3;
Console.WriteLine(Math.Round(1.2345M, x)); // 1.234 (good)
Console.WriteLine(Math.Round(1M, x));      // 1   (would like 1.000)
Console.WriteLine(Math.Round(1.2M, x));    // 1.2 (would like 1.200)

Note that since I want to control the number of places programatically, this string.Format won't work (surely I ought not generate the format string):

Console.WriteLine(
    string.Format("{0:0.000}", 1.2M));    // 1.200 (good)

Should I just include Microsoft.VisualBasic and use FormatNumber?

I'm hopefully missing something obvious here.

+6  A: 

Try

decimal x = 32.0040M;
string value = x.ToString("N" + 3 /* decimal places */); // 32.004
string value = x.ToString("N" + 2 /* decimal places */); // 32.00
// etc.

Hope this works for you. See

http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx

for more information. If you find the appending a little hacky try:

public static string ToRoundedString(this decimal d, int decimalPlaces) {
    return d.ToString("N" + decimalPlaces);
}

Then you can just call

decimal x = 32.0123M;
string value = x.ToRoundedString(3);  // 32.012;
Nick Berardi
How do I specify the number of decimals as a variable? I suppose I could do (1.2M).ToString("D" + x) but that seems a little hacky
Michael Haren
Well you can always turn it in to an extension method.
Nick Berardi
It's growing on me, thanks for the extension method, too.
Michael Haren
Please note: the difference between "F" and "N": "N" will insert a thousands separator while "F" will not.
Michael Haren
+2  A: 

See these links for format string help:
http://msdn.microsoft.com/en-us/library/0c899ak8.aspx
http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx

You want this:

Console.WriteLine(Math.Round(1.2345M, x).ToString("F" + x.ToString()));

Additionally, the .ToString call will round for you if needed so you can skip the Math.Round call and just do this:

Console.WriteLine(1.2345M.ToString("F" + x.ToString()));
Joel Coehoorn
OK, so generating the format string ("F"+x.ToString()) is the trick, then? I assumed I was just missing a library. Thanks, Joel!
Michael Haren
But... you described the exact same thing in the comments of the above answer as "hacky"?
Matt Grande
<tounge in cheek>Once is a hack. Twice is a best practice.</tounge in cheek>
Joel Coehoorn
It's growing on me
Michael Haren
+1  A: 

Something like this should handle it:

int x = 3;
string format = "0:0.";
foreach (var i=0; i<x; i++)
    format += "0";
Console.WriteLine(string.Format("{" + format + "}", 1.2M));
Matt Grande
A: 

Try this to dynamically create your own format string without having to use multiple steps.

Console.WriteLine(string.Format(string.Format("{{0:0.{0}}}", new string("0", iPlaces")), dValue))

In steps

//Set the value to be shown
decimal dValue = 1.7733222345678M;

//Create number of decimal places
int iPlaces = 6;

//Create a custom format using the correct number of decimal places
string sFormat = string.Format("{{0:0.{0}}}", new string("0", iPlaces));

//Set the resultant string
string sResult = string.Format(sFormat, dValue);
Stevo3000
A: 

Method to do that:

private static string FormatDecimal(int places, decimal target)
        {
            string format = "{0:0." + string.Empty.PadLeft(places, '0') + "}";
            return string.Format(format, target); 
        }
Chuck