Форматер валют.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 );

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

Другие вопросы по тегам