Rounding in .Net by ThinqLinq

Rounding in .Net

A while back I was stung by the rounding "bug" and forgot to blog about it.

I was unaware of the fact that Round by default uses accounting rounding where you round to the nearest EVEN value. Thus round(1.5,0)=2 and round(0.5,0) = 0. Although this agrees with the ISO standard, it does not agree with the behavior we are taught to expect in elementary math, nor does it agree with the functionality of .ToString where 0.5.ToString("n0") = "1". This discrepancy can cause your displayed values not to agree with the calculated values if you have interim calculations. For instance, if you show the values of each order item using .ToString("n2") but sum your values with Math.Round(val,2). If you want to use the more expected rounding function, you need to explicitly add the overload for MidpointRounding. I put together a small console app to demonstrate.

Sub Main
Console.WriteLine("round(1.5,0)=" & Math.Round(1.5, 0).ToString)
Console.WriteLine("round(0.5,0)=" & Math.Round(0.5, 0).ToString)
Console.WriteLine("round(0.5,0,AwayFromZero)=" & Math.Round(0.5, 0, MidpointRounding.AwayFromZero).ToString)
Console.WriteLine("round(1.5,0).ToString=" & 1.5.ToString("n0"))
Console.WriteLine("round(0.5,0).ToString=" & 0.5.ToString("n0"))
Console.ReadLine()
End Sub

This code has the following results.

round(1.5,0)=2
round(0.5,0)=0
round(0.5,0,AwayFromZero)=1
round(1.5,0).ToString=2
round(0.5,0).ToString=1

Note the second line where .5 rounds to 0 not 1. The third line is more expected and agrees with the .ToString implementation. It is a hastle explicitly adding the MidpointRounding parameter, but a necessary evil I suppose.

Posted on - Comment
Categories: VB -
comments powered by Disqus