From the documentation on the Math.Round(decimal)
method:
If the fractional component of d is halfway between two integers, one of which is even and the other odd, the even number is returned.
The same logic applies to the Math.Round(decimal, int)
overload. Notice:
Math.Round(0.125, 2) // 0.12
Math.Round(0.135, 2) // 0.14
Math.Round(0.145, 2) // 0.14
It's not 'bad math'; it's a common rounding strategy known as 'round-to-even'. From Wikipedia:
This variant of the round-to-nearest method is also called unbiased rounding, convergent rounding, statistician's rounding, Dutch rounding, Gaussian rounding, odd-even rounding, bankers' rounding or broken rounding, and is widely used in bookkeeping.
This is the default rounding mode used in IEEE 754 computing functions and operators.
If you want finer control over how it rounds, you can specify a MidpointRounding
parameter
Math.Round(0.125, 2, MidpointRounding.AwayFromZero) // 0.13