Подтвердить что ты не робот

Форматировать десятичную запятую, сохранять конечные нули

Я хотел бы преобразовать десятичную строку в строку с запятыми в качестве тысяч разделителей и сохранить ту же точность, с которой была создана десятичная запятая. (Будет иметь 2-5 значащих цифр)

        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

Нет ли встроенного способа сделать это без разбора строки вручную? Если нет ни одной строки формата, какой самый простой способ сделать это?

4b9b3361

Ответ 1

В соответствии с документацией десятичное число сохраняет конечные нули. Вы можете отобразить их, если вы используете спецификатор "G" или вообще не спецификатор. Они теряются, когда вы используете один из спецификаторов, который включает в себя тысячу разделителей.

Если вы хотите указать количество конечных нулей при преобразовании в строку, вы можете сделать это, добавив спецификатор точности (от 0 до 99 цифр) после символа форматирования, например:

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

Результат будет

 1,234.4500

UPDATE: Вы можете получить число десятичных цифр с помощью метода Decimal.GetBits, который возвращает двоичное представление числа. Количество десятичных знаков сохраняется в битах 16-23 (третий байт) четвертого элемента.

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.

Получение строкового представления с использованием всех цифр может быть выполнено следующим образом:

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

который будет производить

1,234.45000

Ответ 2

Поскольку вы планируете иметь число переменных десятичных знаков (2-5), я не думаю, что вы можете выполнить его в строковом формате.

Это решение не обязательно красиво, но оно выполняет свою работу. Обратите внимание, что он выделит несколько строк в этом процессе (я считаю, 5), поэтому он может плохо работать при широкомасштабном использовании. Вы сохраните количество десятичных знаков и получите разделенные запятыми группы в части до десятичной дроби.

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