Rounding under Visual Studio 2019 does not work as expected as outlined in the documentation in certain cases for me.
Under Visual Studio 2019, when I run Math.Round(1.275, 2) I get 1.27. Based on the default rounding it should round to the nearest even digit 1.28. If I run Math.Round(0.275, 2) I get 0.28.
CodePudding user response:
The documentation does also give you the reason for this unexpected behavior:
When rounding midpoint values, the rounding algorithm performs an equality test. Because of problems of binary representation and precision in the floating-point format, the value returned by the method can be unexpected. For more information, see Rounding and precision.
Floating point numbers are stored according to IEEE 754 which is not always a precise representation of the actual value you want to store. You will find lots of ressources where you can learn about how floating point numbers are represented in binary and how exactly IEEE 754 works.
CodePudding user response:
Two things here.
First, this is likely a result of the underlying representation of floats. The documentation itself warns:
When rounding midpoint values, the rounding algorithm performs an equality test. Because of problems of binary representation and precision in the floating-point format, the value returned by the method can be unexpected.
Second, The Math.Round
function also takes a rounding strategy argument as the third parameter. Based on the default rounding strategy, this behavior actually seems inline with what the documentation specified. Check out this example they have:
// 3.4 = Math.Round( 3.45, 1)
// -3.4 = Math.Round(-3.45, 1)
// 3.4 = Math.Round(3.45, 1, MidpointRounding.ToEven)
// 3.5 = Math.Round(3.45, 1, MidpointRounding.AwayFromZero)
// 3.4 = Math.Round(3.47, 1, MidpointRounding.ToZero)
// -3.4 = Math.Round(-3.45, 1, MidpointRounding.ToEven)
// -3.5 = Math.Round(-3.45, 1, MidpointRounding.AwayFromZero)
// -3.4 = Math.Round(-3.47, 1, MidpointRounding.ToZero)
It seems to me that the default tries to round to the the closest integer. For example, 2.75 is closer to 3 than 2 so it gets rounded to 2.8. The opposite applies to 1.275. Maybe I'm mistaken, but either way, check out the MidpointRounding argument — that should probably solve your problem.