Форматер валют.NET: можно ли указать порядок использования банковского округления?
Кто-нибудь знает, как я могу получить строку формата для округления банкиров? Я использовал "{0:c}", но это не округляет так же, как округление банкиров. Math.Round()
метод делает банкиров округлением. Мне просто нужно иметь возможность дублировать способ округления, используя строку формата.
Примечание: первоначальный вопрос вводил в заблуждение, и из него вытекают ответы с упоминанием регулярных выражений.
5 ответов
Разве вы не можете просто вызвать Math.Round() для ввода строки, чтобы получить желаемое поведение?
Вместо:
string s = string.Format("{0:c}", 12345.6789);
Делать:
string s = string.Format("{0:c}", Math.Round(12345.6789));
Regexp - это язык сопоставления с образцом. Вы не можете выполнять арифметические операции в регулярном выражении.
Проведите несколько экспериментов с IFormatProvider и ICustomFormatter. Вот ссылка может указывать вам в правильном направлении. http://codebetter.com/blogs/david.hayden/archive/2006/03/12/140732.aspx
Если вы используете.NET 3.5, вы можете определить метод расширения, который поможет вам сделать это:
public static class DoubleExtensions
{
public static string Format(this double d)
{
return String.Format("{0:c}", Math.Round(d));
}
}
Затем, когда вы звоните, вы можете сделать:
12345.6789.Format();
Это невозможно, регулярное выражение не имеет понятия "числа". Вы могли бы использовать оценщик совпадений, но вы бы добавили императивный код на C# и отклонились бы от требований только регулярных выражений.
В.Net встроена поддержка округления арифметики и банкиров:
//midpoint always goes 'up': 2.5 -> 3
Math.Round( input, MidpointRounding.AwayFromZero );
//midpoint always goes to nearest even: 2.5 -> 2, 5.5 -> 6
//aka bankers' rounding
Math.Round( input, MidpointRounding.ToEven );
"Четное" округление фактически является значением по умолчанию, хотя "вдали от нуля" - это то, что вы выучили в школе.
Это связано с тем, что под капотом компьютерные процессоры также делают округление банкиров.
//defaults to banker's
Math.Round( input );
Я бы подумал, что любая строка формата округления будет по умолчанию округлять банкиров, разве это не так?