Math.Round function is commonly used in many applications. However this function may not operate as expected and return expected result in some situations. This is a crutial issue to prevent wrong calculations in our applications.
Math.Round(1.44, 1); //Expected: 1.4 Result 1.4
Math.Round(1.45, 1); //Expected: 1.5 Result 1.4
Math.Round(1.46, 1); //Expected: 1.5 Result 1.5
Math.Round(1.54, 1); //Expected: 1.5 Result 1.5
Math.Round(1.55, 1); //Expected: 1.6 Result 1.6
Math.Round(1.56, 1); //Expected: 1.6 Result 1.6
As seen above when we rounded value of 1,45 to one digit the result was 1,4 instead of 1,5. However same problem was not seen while rounding the value of 1,55 to one digit. The reason of this result is that .Net Framework uses bankers rounding as default rounding system. In bankers rounding system if the value of the digits in d to the right of the decimals position is halfway between the digit in position decimals, that digit is rounded up if it is odd, or left unchanged if it is even. If the precision of d is less than decimals, d is returned unchanged.
private decimal MyRound(decimal number, int decimals)
{
return decimal.Round(number, decimals, MidpointRounding.AwayFromZero);
}
As a solution of this problem we can use Decimal.Round(Decimal, Int32, MidpointRounding) overload instead of Math.Round function. MidpointRounding enum has AwayFromZero and ToEven options. While ToEven acts as default behaviour in .Net Framework AwayFromZero option acts as we commonly use.