I’m trying to reproduce in C# the behavior of the T-SQL Round function when a truncate function is used.
This is the SQL behavior I’m trying to reproduce in C#:
SELECT ROUND(150.757,2,0) -- 150.76
SELECT ROUND(150.757,2,1) -- 150.75
SELECT ROUND(150.747,2,0) -- 150.75
SELECT ROUND(150.747,2,1) -- 150.74
In System.Math there are two methods that I tried to use.
The first one, Math.Truncate truncates to the whole part only, so it won’t help me.
The other method is Math.Round.
This method has 2 interesting overloads.
Math.Round(decimal,int)
Math.Round(decimal,int,System.MidpointRounding)
The MidpointRounding enumeration options are:
System.MidpointRounding.AwayFromZero
// When a number is halfway between two others,
// it is rounded toward the nearest number that is away from zero.
System.MidpointRounding.ToEven
// When a number is halfway between two others,
// it is rounded toward the nearest even number.
Executing the two overloads of Math.Round with the same data as SQL I’ve got the following result:
Math.Round(150.757, 2, MidpointRounding.AwayFromZero) // 150.76
Math.Round(150.757, 2, MidpointRounding.ToEven) // 150.76
Math.Round(150.747, 2, MidpointRounding.AwayFromZero) // 150.75
Math.Round(150.747, 2, MidpointRounding.ToEven) // 150.75
Given that none of the MidpointRounding solve my problem, what is the best way to reproducte the T-SQL function in C#?
Update:
After implementing Paul’s answer I noticed one extra odd behavior from T-SQL ROUND function:
SELECT ROUND(150.747,-2,1) // 100
SELECT ROUND(150.747,-2) // 200
I edited Paul’s answer to include support for this edge case.
I imagine somebody will come up with a better way, but this is certainly a possible way!
Output:
A more complete implementation would look something like this: