views:

740

answers:

6

Does anyone know how I can get a format string to use bankers rounding? I have been using "{0:c}" but that doesn't round the same way that bankers rounding does. The Math.Round() method does bankers rounding. I just need to be able to duplicate how it rounds using a format string.


Note: the original question was rather misleading, and answers mentioning regex derive from that.

+2  A: 

Regexp is a pattern matching language. You can't do arithmetic operations in Regexp.

Do some experiements with IFormatProvider and ICustomFormatter. Here is a link might point you in the right direction. http://codebetter.com/blogs/david.hayden/archive/2006/03/12/140732.aspx

jop
A: 

Its not possible, a regular expression doesn't have any concept of "numbers". You could use a match evaluator but you'd be adding imperative c# code, and would stray from your regex only requirement.

viggity
A: 

You can create an extension method that will pre-process numbers to use banker's rounding and then pass the result into the actual string.Format();

something like

BankersFormat("{0:c}", myNum);

which would do some evaluations via regex and then do a math.Round on each parameter passed in that is formatted as currency.

Orion Adrian
+3  A: 

Can't you simply call Math.Round() on the string input to get the behavior you want?

Instead of:

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

Do:

string s = string.Format("{0:c}", Math.Round(12345.6789));
Zach Lute
I'm sure that this functionality solves the problem, but it adds extra headache and code calling. I've experienced this problem before as well, which I guess could be expressed as: "Are there format strings for rounding?:
David Sokol
A: 

.Net has built in support for both Arithmetic and Bankers' rounding:

//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 );

"To even" rounding is actually the default, even though "away from zero" is what you learnt at school.

This is because under the hood computer processors also do bankers' rounding.

//defaults to banker's
Math.Round( input );

I would have thought that any rounding format string would default to bankers' rounding, is this not the case?

Keith
The reason we do banker's rounding is that it (normally) gives a closer result - since odds and evens are usually fairly uniformly distributed, you'll sometimes be taking $0.005 and sometimes giving $0.005. I'm not sure that CPU's care either way, but our accountants sure do....
Mark Brackett
The CPUs do - for precisely that reason. That's why ToEven is the default - it eliminates bias (or at least evens it out). This is useful in floating point calculations, just as it is in banking.
Keith
A: 

If you are using .NET 3.5, you can define an extension method to help you do this:

public static class DoubleExtensions
{
    public static string Format(this double d)
    {
        return String.Format("{0:c}", Math.Round(d));
    }
}

Then, when you call it, you can do:

12345.6789.Format();
Abe Heidebrecht