Search code examples
c#.netroundingbankers-rounding

Math.Round(1.225,2) gives 1.23, shouldn't it give 1.22


AFAIK .NET's default round option is to even, so Math.Round(1.225,2) should give 1.22 but it gives 1.23.

Math.Round(2.225,2) = 2.22 
Math.Round(100.225,2) = 100.22 

all the values I tried rounds to nearest even but only 1.225 and -1.225 rounds to 1.23 and -1.23.


Solution

  • The main problem is that in float and double, the amount of decimal places is not part of the value, and the precision isn't decimal, but rather, binary. And there's no finite binary number that can represent 1.225 exactly.

    So when you do Math.Round(1.225f, 2), you're actually doing something more like Math.Round(1.22500002f, 2) - there's no midpoint rounding involved.

    The same problem appears with Math.Round(2.225f, 2) - it's just that the "real" value is slightly smaller than 2.225f, so the result rounds down. But there's still no midpoint rounding involved.

    If you need decimal precision, use decimal. Neither float nor double are designed for decimal precision - they're fine for e.g. physics calculations, but not for e.g. accounting.