16

I'd like to group the digits in a double by thousands, but also output however number of decimals are actually in the number. I cannot figure out the format string.

 1000 => 1,000
 100000 => 100,000
 123.456 => 123.456
 100000.21 => 100,000.21
 100200.123456 => 100,200.123456

Disclaimers (it's not as straight forward as you think):

  • Please do not point me to this question it does not answer my question
  • Please do not point me to MSDN, the articles have not helped me. (If you believe I'm reading them incorrectly, read them yourself and post the correct answer)
  • .ToString("n") does not work, it rounds the digits
Community
  • 1
  • 1
Tom Ritter
  • 99,986
  • 30
  • 138
  • 174

6 Answers6

11

This appears to do exactly what you want:

public void Code(params string[] args)
{
    Print(1000);
    Print(100000);
    Print(123.456);
    Print(100000.21 );
    Print(100200.123456);
}

void Print(double n)
{
    Console.WriteLine("{0:###,###.#######}", n);
}

1,000
100,000
123.456
100,000.21
100,200.123456
James Curran
  • 101,701
  • 37
  • 181
  • 258
  • If you have more than 7 decimal places, won't that truncate it? – MusiGenesis Nov 17 '08 at 15:43
  • It appears so, which is less than ideal, but I can push it out to 12 decimal places which should be a limit for my purposes. – Tom Ritter Nov 17 '08 at 15:45
  • 1
    Won't work for an arbitrary number of decimals, though. Since double has precision of 15-16 digits, though "{0:##,###,###,###,###,##0.###############}" would seem to capture all possible doubles with all possible digits. Notice I prefer a leading 0. – tvanfosson Nov 17 '08 at 15:46
  • Thanks for the format mask James, great job. One thing we fixed/added was that when we were receiving 0.1, it was just doing showing .1, removing the 0. To prevent that, we used the following mask: {0:#,##0.##########} – GR7 Jun 24 '13 at 19:18
2

An old thread, but none of the answers looks entirely satisfactory to me. Most of them turn zero into the empty string, including the one with the most upvotes.

I think a better solution is "#,##0.#################", which does at least show zeroes. It's still ugly though. There must be a better way.

double[] vals = new double[] { 0.0, 0.1234, -0.1234, 1.0, 
                               123456789.123456, 123456789.0, 
                               0.123456789123456 };
foreach (double val in vals) 
{ 
    Console.WriteLine(val + ": " + val.ToString("#,##0.#################")); 
}
forsvarir
  • 10,749
  • 6
  • 46
  • 77
1

Try simply use "#,#", this adds the commas for thousands et al, but I don't know if it will keep the decimals, otherwise "#,###.####################", or any number of '#' symbols that you want after the decimal.

dragonjujo
  • 358
  • 1
  • 2
  • 10
0

Try this one:

VB:

Dim vals() As Double = {1000, 100000, 123.456, 100000.21, 100200.123456}
For Each val As Double in vals
   Console.WriteLine(val.ToString("###,###.#########"))
Next val

C#:

double[] vals = new double[] {1000, 100000, 123.456, 100000.21, 100200.123456};
foreach (double val in vals)
{
    Console.WriteLine(val.ToString("###,###.#########"));
}

The problem is that there is no format to handle an arbitrary number of decimals. However, since you can only store a very limited precision, you can just use that and add a few more # characters as needed to cover it, assuming you're willing to let it cut off any insignificant 0's.

And the MSDN link you posted is the exact place you'd go to read how to do this.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
0

You can create a custom format string .ToString("###,###.######") Custom Numeric Format Strings

Aaron Fischer
  • 20,853
  • 18
  • 75
  • 116
0

This could be a little slow, but it will do what you want.

public static string FormatNumber(double num)
{
    string s = num.ToString();
    string result = "";

    if(s.IndexOf('.') != -1)
    {
        result = s.Substring(s.IndexOf('.'));
        s = s.Substring(0, s.IndexOf('.'));
    }

    while (s.Length > 3)
    {
        result = "," + s.Substring(s.Length - 3);
        s = s.Substring(0, s.Length - 3);
    }
    if (s.Length == 0)
        return result.Substring(1);
    return s + result;
}
LeppyR64
  • 5,251
  • 2
  • 30
  • 35
  • 1
    Downvoting is a little harsh for something that answers the question no? While it's not the best solution, it is a solution. – LeppyR64 Nov 17 '08 at 17:22