10

I need to convert a decimal number to formatted string with thousand groups and unlimited (variable) decimal numbers:

1234 -> "1,234"
1234.567 -> "1,234.567"
1234.1234567890123456789 -> "1,234.1234567890123456789"

I tried String.Format("{0:#,#.#}", decimal), but it trims any number to max 1 decimal place.

Bassie
  • 9,529
  • 8
  • 68
  • 159
jurev
  • 1,457
  • 1
  • 14
  • 22
  • Be aware that the [decimal type has a precision of 28-29 digits](http://msdn.microsoft.com/en-us/library/364x0z75.aspx) – xanatos Oct 17 '11 at 14:28

3 Answers3

20

You can use # multiple times (see Custom Numeric Format Strings):

string.Format("{0:#,#.#############################}", decimalValue)

Or, if you're just formatting a number directly, you can also just use decimal.ToString with the format string.

However, there is no way to include "unlimited decimal numbers". Without a library supporting arbitrary precision floating point numbers (for example, using something like BigFloat from Extreme Numerics), you'll run into precision issues eventually. Even the decimal type has a limit to its precision (28-29 significant digits). Beyond that, you'll run into other issues.

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • Unfortunatelly this is not a general solution for all decimal types (like double). – jurev Oct 17 '11 at 14:33
  • @jurev: It is, but only to the limit of precision of the type in question. As I said, all standard floating point types have a limited precision - you can only work to the precision of the type. – Reed Copsey Oct 17 '11 at 14:34
  • 1
    @jurev: `double` is not a decimal type, it's a binary floating point with limited precision. – Ben Voigt Oct 17 '11 at 14:34
  • @jurev to be precise, 15-16 digits http://msdn.microsoft.com/en-us/library/678hzkk9.aspx – xanatos Oct 17 '11 at 14:52
9

As I've said, the decimal type has a precision of 28-29 digits.

decimal mon = 1234.12345678901234567890123M;
var monStr = mon.ToString("#,0.##############################");
var monStr2 = String.Format("{0:#,0.##############################}", mon);

Here there are 30x# after the decimal separator :-)

I've changed one # with 0 so that 0.15 isn't written as .15 .

xanatos
  • 109,618
  • 12
  • 197
  • 280
1

this should do the trick

string DecimalToDecimalsString(decimal input_num)
        {            
            decimal d_integer = Math.Truncate(input_num); // = 1234,0000...
            decimal d_decimals = input_num-d_integer; // = 0,5678...

            while (Math.Truncate(d_decimals) != d_decimals)
                d_decimals *= 10; //remove decimals

            string s_integer = String.Format("{0:#,#}", d_integer);
            string s_decimals = String.Format("{0:#}", d_decimals);

            return s_integer + "." + s_decimals;
        }

replacing decimal with other types should work too.

Alex
  • 23,004
  • 4
  • 39
  • 73
  • Interesting solution, however it does not work for international formatting (some countries have even different 1000's group separators for integer and decimal part). – jurev Oct 17 '11 at 14:55