Why does Math.Round(2.5) return 2 instead of 3?

Firstly, this wouldn’t be a C# bug anyway – it would be a .NET bug. C# is the language – it doesn’t decide how Math.Round is implemented.

And secondly, no – if you read the docs, you’ll see that the default rounding is “round to even” (banker’s rounding):

Return Value
Type: System.Double
The integer nearest a. If the
fractional component of a is halfway
between two integers, one of which is
even and the other odd, then the even
number is returned. Note that this
method returns a Double instead of an
integral type.

Remarks
The behavior of this method follows IEEE Standard 754,
section 4. This kind of rounding is
sometimes called rounding to nearest,
or banker’s rounding. It minimizes
rounding errors that result from
consistently rounding a midpoint value
in a single direction.

You can specify how Math.Round should round mid-points using an overload which takes a MidpointRounding value. There’s one overload with a MidpointRounding corresponding to each of the overloads which doesn’t have one:

Whether this default was well chosen or not is a different matter. (MidpointRounding was only introduced in .NET 2.0. Before then I’m not sure there was any easy way of implementing the desired behaviour without doing it yourself.) In particular, history has shown that it’s not the expected behaviour – and in most cases that’s a cardinal sin in API design. I can see why Banker’s Rounding is useful… but it’s still a surprise to many.

You may be interested to take a look at the nearest Java equivalent enum (RoundingMode) which offers even more options. (It doesn’t just deal with midpoints.)

Leave a Comment