C# Double — форматирование ToString для отображения значения в центах без отображения десятичного числа

У меня есть ситуация, когда мне нужно отобразить двойное значение, округленное до двух знаков после запятой, но отображаемое без десятичного знака. Будут некоторые ситуации, когда я захочу использовать один и тот же код и отображать двойное значение по-разному, поэтому я надеялся, что смогу справиться с этим, передав шаблон строкового формата.

Например, двойное значение может быть: 11367,2232. Я хочу, чтобы значение было: 1136722.

Другой пример: значение может быть 344576,3457. Я хочу, чтобы значение было 34457635.

Третий пример, значение может быть 546788. Я хочу, чтобы значение было 54678800.

Итак, я хочу сделать что-то это:

String.Format("{PATTERN}", dblCurrency);

Существует ли какой-либо шаблон форматирования, который бы округлял до 2 знаков после запятой и не отображал десятичное число?


person R J    schedule 28.07.2010    source источник
comment
В этом примере я должен был назвать переменную dblValue вместо обращения к ней как к валюте. Он не представляет валюту.   -  person R J    schedule 28.07.2010


Ответы (4)


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

Во-вторых, округление и форматирование отображения — это отдельные операции, и ваш код должен выражать их отдельно. string.Format() не предоставляет единую маску формата, которая будет делать и то, и другое, но вы можете легко добиться того, что ищете:

decimal amount = 11367.3456m
String.Format( "{0:0}", amount*100 );

который выведет:

1136735

Спецификатор формата D0 выдает числовые значения без каких-либо разделителей и цифр после запятой. Вы также можете просто использовать ToString(), но я думаю, что спецификатор формата более четко передает намерение.

person LBushkin    schedule 28.07.2010
comment
Если бы я мог сделать +2, я бы сделал это, особенно за комментарий о десятичном и двойном. - person ; 28.07.2010
comment
Спецификатор формата уже округляется, вам не нужен Math.Round(). - person Hans Passant; 28.07.2010
comment
Я получаю сообщение об ошибке с этим кодом. Ошибка FormatException. Недопустимый спецификатор формата. - person R J; 28.07.2010
comment
@ rj8: Да, я ошибся. Спецификатор формата D можно использовать только с целочисленными типами. На самом деле достаточно использовать {0:0} в качестве формата; в этом случае вызов Math.Round() не нужен (как заявил Ганс). Я обновил свой пример кода. - person LBushkin; 29.07.2010
comment
Я полагаю, что это так хорошо, как я собираюсь получить. Я согласен с десятичным и двойным, но на самом деле это не для валюты. Я думал о валюте, потому что надеялся, что в .NET может быть что-то встроенное для обработки сценария, в котором вы хотите выразить десятичное значение в общем количестве центов. Просто казалось, что это может быть общий сценарий. В любом случае, для этой функции мне просто нужно иметь дело с параметрами для обоих шагов; округление и умножение. - person R J; 29.07.2010

Использовать это:

var dblCurrency = 11367.2232D;
var rounded = Math.Round(dblCurrency, 2);
var cents = rounded*100;
var centString = cents.ToString();
person Byron Sommardahl    schedule 28.07.2010

Вы можете использовать пользовательскую функцию форматирования, например:

string ScaledFormat(string format, double value, double scaleFactor)
{
    return(string.Format(format, Math.Round(value * scalefactor, 0)));
}

или, если у вас есть только несколько стилей формата, я бы использовал перечисление:

enum CustomFormat { Integer, IntegerX100 };
string ScaledFormat(CustomFormat format, double value)
{
    switch(format)
    {
        case CustomFormat.Integer:     return(string.Format("{0}", (int) value);
        case CustomFormat.IntegerX100: return(string.Format("{0}", Math.Round(value * 100.0, 0));
    }
}

Это означает, что существует определенное количество способов форматирования значения, а фактическое преобразование полностью инкапсулировано в методе, что обеспечивает согласованный вывод по всей программе и позволяет избежать разбрасывания «магических констант» повсюду. Он также централизует форматирование, чтобы вы могли легко настроить его в будущем без необходимости находить и исправлять сотни различных вызовов string.Format и уменьшать необходимое тестирование, поскольку вы просто повторно используете небольшой фрагмент хорошо протестированного кода. И это делает случаи, когда вы форматируете строку, намного проще для чтения/понимания (самодокументирующий код).

person Jason Williams    schedule 28.07.2010

Чтобы получить то, что вам нужно, попробуйте что-то вроде:

decimal dNumber = 11367.2232;
String.Format( "{0:0}", Math.Round(amount, 2) * 100));

Это должно вывести 1136722.

person Seb    schedule 28.07.2010