简体   繁体   中英

Format decimal with commas, preserve trailing zeros

I'd like to convert a decimal to a string, with commas as thousands seperators, and preserve the same precision the decimal was created with. (Will have 2-5 significant digits)

        decimal d = 1234.4500M;

        //I'd like "1,234.4500"

        var notRight = d.ToString("###,###.#######");     //1,234.45
        var alsoNotRight = d.ToString("###,###.00000");;  //1,234.45000
        var notRightEither = d.ToString("N");    //1,234.45
        var notRightEither2 = d.ToString("G");   //1234.45000

Is there no built in way to do this without parsing the string manually? If there is no single format string, what's the easiest way to do this?

According to the documentation , a decimal number preserves the trailing zeros. You can display them if you use the "G" specifier or no specifier at all. They are lost when you use one of the specifiers that includes a thousand separator.

If you want to specify the number of trailing zeros when converting to string, you can do it by adding a precision specifier (0 to 99 digits) after the format character, like this:

decimal d=1234.45M;
var numberAsString=d.ToString("N4");

The result will be

 1,234.4500

UPDATE: You can get the number of decimal digits using the Decimal.GetBits method which returns the binary representation of the number. The number of decimals is stored in bits 16-23 (third byte) of the fourth element.

The fourth element of the returned array contains the scale factor and sign. It consists of the following parts:

...

Bits 16 to 23 must contain an exponent between 0 and 28, which indicates the power of 10 to divide the integer number.

Getting a string representation using all digits can be done like this:

decimal d=1234.45000M;
var nums=Decimal.GetBits(d);
var decimals=BitConverter.GetBytes(nums[3])[2];
var formatStr="N"+decimals;
d.ToString(formatStr);

which will produce

1,234.45000

Since you plan on having a variable number of decimal places (2-5) , I don't think you can pull it off via a string format.

This solution is not necessarilly pretty, but it gets the job done. Do note that it will allocate several strings in the process (I believe 5), so it may not perform well in large-scale use. You will retain the number of decimal places, and get comma separated groups in the portion before the decimal.

public static string FormatDecimal(decimal d)
{
    return d.ToString("N0") + // Format portion before decimal
           "." + 
           d.ToString().Split('.')[1];  // Retain number of decimal places
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM