Search code examples
c#tostringnumber-formatting

Format number to string with custom group and decimal separator without changing precision


I would like to format some numbers to strings in C# with custom group/thousands separator and decimal separator. The group and decimal separator can change based on user input so I would like to use a NumberFormatInfo object instead of a hardcoded formatting string. My code below gets the proper separators, but it changes the precision of the number to always be two decimal places, whereas I want to keep the full precision of the number and only show decimal places when needed (so integer values dont have decimal places).

How can I achieve this? I am guessing I need to change the "N" parameter, but change it to what?

double n1 = 1234;
double n2 = 1234.5;
double n3 = 1234567.89;
double n4 = 1234.567;

var nfi = new NumberFormatInfo();
nfi.NumberDecimalSeparator = ",";
nfi.NumberGroupSeparator = " ";

string s1 = n1.ToString("N", nfi); //want "1 234" but I get "1 234,00"
string s2 = n2.ToString("N", nfi); //want "1 234,5" but I get "1 234,50"
string s3 = n3.ToString("N", nfi); //correct output of "1 234 567,89" 
string s4 = n4.ToString("N", nfi); //want " 1 234,567" but I get "1 234,57"

Solution

  • Below is the solution I came up with as an extension method.

    public static string Format(this double d, NumberFormatInfo numberFormatInfo)
    {
        string s = d.ToString(CultureInfo.InvariantCulture);
        int index = s.IndexOf('.');
        int decimalPlaces = index == -1 ? 0 : s.Length - index - 1;
        return d.ToString($"N{decimalPlaces}", numberFormatInfo);
    }