2

I am developing an application for some guys very picky about numerical accuracy (they are dealing among others with accounting and very accurate telecom variables). For this reason I am using the decimal type everywhere, because the float and double types are not suitable (do not hesitate to redirect me to an existing better datatype).

My problem comes when I need to format those numbers. The requirement is to display as many decimal digit as needed but at least 2 and also to use a group separator for thousands.

For example:

Value       Formatted
1                1.00
1000         1,000.00
1.5              1.50
1000.355    1,000.355
0.000035     0.000035

So I went the MSDN looking for numeric string formats. I found this useful resource Standard Numeric Formats but none of my tries works as expected (N, N2, F, F2, G, G2, etc, I tried various combinations even when I didn't believe in them ^^ - I even try some F2# for fun).

My conclusion is there is not a built-in format to do what I want. Right?

So I checked out the next chapter Custom Numeric Formats. But I couldn't find a combination that suit my needs. So I went to SO and find a lots of question about that (1, 2, and so on).

These questions let me fear that the only solution is this one: #,##0.00####### with as many trailing # as I need precision.

Am I right?

I guess that with 12 #, my guys won't find any accuracy issue, but I might have missed the magical format I need?

fharreau
  • 2,105
  • 1
  • 23
  • 46

3 Answers3

2

This is probably what you're looking for:

static string FormatNumber(string input)
{
    var dec = decimal.Parse(input);
    var bits = decimal.GetBits(dec);
    var prec = bits[3] >> 16 & 255;
    if (prec < 2)
        prec = 2;
    return dec.ToString("N" + prec);
}

When you call it, do a ToString() on decimals, and convert the result back to decimal if needed.

I tried your example numbers, and the result:

enter image description here

Based on this SO answer.

Sach
  • 10,091
  • 8
  • 47
  • 84
1

I created a little function: it formats the number based on how many decimal places it has:

    public static void Main()
    {
        decimal theValue;
        theValue = 0.000035M;
        Console.WriteLine(theFormat(theValue));
        theValue = 1.5M;
        Console.WriteLine(theFormat(theValue));
        theValue = 1;
        Console.WriteLine(theFormat(theValue));                 
    }
    public static decimal theFormat(decimal theValue){
        int count = BitConverter.GetBytes(decimal.GetBits(theValue)[3])[2];
        return count > 1?theValue:Convert.ToDecimal(string.Format("{0:F2}", theValue));
    }

This, produces the following output:

0.000035
1.50
1.00
Hackerman
  • 12,139
  • 2
  • 34
  • 45
0

If you want a total control over formatting you can implement your own IFormatProvider for decimals. Inside of it you can use StringBuilder and do anything you need with no restrictions of string.Format().

Kostya
  • 849
  • 5
  • 14