Consider the following code sample:
var tests = new List<double> { 131.505, 131.515, 131.525, 131.535, 131.545, 131.555, 131.565, 131.575, 131.585, 131.595 };
foreach (double n in tests)
{
Console.WriteLine("{0} => {1}", n, Math.Round(n, 2, MidpointRounding.ToEven));
}
131.505 => 131.5
131.515 => 131.51 <- wt*
131.525 => 131.52
131.535 => 131.54
131.545 => 131.54
131.555 => 131.56
131.565 => 131.56
131.575 => 131.57 <- wt*
131.585 => 131.58
131.595 => 131.6
131.515 => 131.52
131.575 => 131.58
Why does MidpointRounding.ToEven
algorithm produce a number that has an odd number at the end; and is there something I could do to fix this?
Background: I am passing the same numbers to PHP round($n, 2, PHP_ROUND_HALF_EVEN)
function. The objective is to have both scripts produce same results.
I would appreciate an explanation of what is going on behind the scenes in this particular example instead of a canned "because floating point math is broken" response. I would like to know why PHP is able to produce the expected results but .NET is not? I would like to know if .NET's floating point is broken instead of floating point itself.