Рассмотрим следующий пример кода:
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
Почему алгоритм MidpointRounding.ToEven
выдает число с нечетным числом в конце; и могу ли я что-нибудь сделать, чтобы это исправить?
Справочная информация: я передаю те же цифры в функцию PHP round($n, 2, PHP_ROUND_HALF_EVEN)
. Цель состоит в том, чтобы оба сценария дали одинаковые результаты.
Я был бы признателен за объяснение того, что происходит за кулисами в этом конкретном примере, вместо стандартного ответа "потому что математика с плавающей запятой сломана". Я хотел бы знать, почему PHP может дать ожидаемые результаты, а .NET нет? Я хотел бы знать, если с плавающей точкой .NET сломана вместо самой с плавающей точкой.