Midpoint Rounding

Today I had a strange issue with currencies being 0.01 off. I’ve always been wary of float/double representation of decimals so I’ve stuck to the decimal type in C# for currency.
Despite this, Math.Round(222.485m, 2) was giving me 222.48 – which is not what I learnt at school!

Turns out .NET Core defaults to something called bankers rounding:

This kind of rounding is sometimes called round half to even or banker’s rounding. It minimizes rounding errors that result from consistently rounding a midpoint value in a single direction.

This, according to the documentation follows IEEE Standard 754, section 4, and means that 222.485 rounds to 222.48, but 222.495 rounds to 222.50.

Thankfully, since this wasn’t relevant to this case, it can be disabled with an extra argument, Math.Round(222.485m, 2, MidpointRounding.AwayFromZero) giving me my expected answer of 222.49.