Средство форматирования валюты .NET: могу ли я указать использование банковского округления?

Кто-нибудь знает, как я могу получить строку формата для использования банковского округления ? Я использовал "{0:c}", но это не округляет так же, как округление банкиров. Метод Math.Round() выполняет округление банкиров. Мне просто нужно иметь возможность дублировать, как он округляется, используя строку формата.


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


person user21767    schedule 24.09.2008    source источник
comment
Что за регулярное выражение {0:c}? Для меня это больше похоже на строку формата .NET...   -  person Shog9    schedule 24.09.2008
comment
Просто из любопытства, почему это должно быть регулярным выражением? Кажется, что использование существующего кода было бы безопаснее, так как вероятность того, что он будет содержать ошибки, меньше.   -  person Derek Park    schedule 24.09.2008
comment
что такое округление банкира? Вверх, если в пользу банка, в противном случае?   -  person Matthias Winkelmann    schedule 24.09.2008
comment
@MattW: Banker's Rounding — это лекарство для людей, которые округляются на 0.5. 0.5 находится ровно посередине между 0 и 1, но не ближе к ним. Решение, что вы всегда будете округлять в большую сторону, приводит к предвзятости (например, налог, который вы платите, не должен всегда округляться в большую сторону — это просто несправедливо). Банковское округление настроено таким образом, что в половине случаев округления в большую сторону и в половине случаев в меньшую сторону это выравнивает ситуацию. Алгоритм всегда округляется до четной цифры. например: 0.5 -> 0, 1.5 -> 2, 2.5 -> 2, 3.5 -> 4, 4.5 -> 4   -  person Ian Boyd    schedule 09.09.2011


Ответы (5)


Разве вы не можете просто вызвать Math.Round() для ввода строки, чтобы получить желаемое поведение?

Вместо:

string s = string.Format("{0:c}", 12345.6789);

Do:

string s = string.Format("{0:c}", Math.Round(12345.6789));
person Zach Lute    schedule 24.09.2008
comment
Я уверен, что этот функционал решает проблему, но добавляет лишней головной боли и вызовов кода. Я сталкивался с этой проблемой и раньше, что, я думаю, можно выразить так: существуют ли строки формата для округления?: - person David J. Sokol; 24.09.2008
comment
Это не работает в сценариях, где вы можете указать только строку формата, например, при использовании DisplayFormatAttribute. - person Immortal Blue; 10.07.2015

Regexp — это язык сопоставления с образцом. Вы не можете выполнять арифметические операции в Regexp.

Проведите несколько экспериментов с IFormatProvider и ICustomFormatter. Вот ссылка может указать вам в правильном направлении. http://codebetter.com/blogs/david.hayden/archive/2006/03/12/140732.aspx

person jop    schedule 24.09.2008

Это невозможно, регулярное выражение не имеет понятия «числа». Вы можете использовать оценщик соответствия но вы бы добавили императивный код С# и отклонились бы от вашего требования только к регулярному выражению.

person viggity    schedule 24.09.2008

В .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 );

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

person Keith    schedule 24.09.2008
comment
Причина, по которой мы используем банковское округление, заключается в том, что оно (обычно) дает более близкий результат - поскольку шансы и четы обычно распределяются довольно равномерно, вы иногда берете 0,005 доллара, а иногда даете 0,005 доллара. Я не уверен, что ЦП это волнует, но наших бухгалтеров это точно волнует... - person Mark Brackett; 25.09.2008
comment
Процессоры - именно по этой причине. Вот почему ToEven используется по умолчанию — он устраняет предвзятость (или, по крайней мере, выравнивает ее). Это полезно при вычислениях с плавающей запятой, как и в банковском деле. - person Keith; 26.09.2008

Если вы используете .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();
person Abe Heidebrecht    schedule 24.09.2008