trousyt
trousyt

Reputation: 356

.Net decimal rounding oddities

I'm having the hardest time understanding why the Math.Round function in .NET (using framework 4.5) is behaving a certain way:

Math.Round(21.4451m, 2, MidpointRounding.ToEven) // 21.45

When I call the same with the last decimal place set to 0 instead:

Math.Round(21.4450m, 2, MidpointRounding.ToEven) // 21.44

Can someone explain to me why the rounding result is 21.45 on the first example when the last decimal place is 1 or more?

I need to know as I'm trying to write an algorithm in SQL Server that matches exactly what the .NET framework is doing (since SQL Server uses Arithmetic rounding).

Upvotes: 1

Views: 80

Answers (1)

joordan831
joordan831

Reputation: 720

You are rounding to 2 decimal places. And you are using ToEven:

When a number is halfway between two others, it is rounded toward the nearest even number.

Any number greater than 21.445 (>21.445) will round to 21.45

And any number less than or equal to 21.445 (<=21.445) will round to 21.44.

Math.Round(21.44500001m, 2, MidpointRounding.ToEven); //>21.445 therefore 21.45
Math.Round(21.44500000m, 2, MidpointRounding.ToEven); //=21.445 therefore 21.44
Math.Round(21.44499999m, 2, MidpointRounding.ToEven); //<21.445 therefore 21.44

It's working correctly. ;)

In order to have the same ROUND behavior as in SQL, use AwayFromZero.

SELECT ROUND(21.4451, 2), ROUND(21.4450, 2), ROUND(21.4449, 2)
--less decimal casting, yields:
--     21.4500            21.4500            21.4400

Math.Round(21.44500001m, 2, MidpointRounding.AwayFromZero); //21.45
Math.Round(21.44500000m, 2, MidpointRounding.AwayFromZero); //21.45
Math.Round(21.44499999m, 2, MidpointRounding.AwayFromZero); //21.44

Upvotes: 4

Related Questions