При указании количества десятичных знаков, корректно ли поведение Math.Round с MidpointRounding.ToEven?
Я пытаюсь использовать Math.Round, однако результаты, которые я получаю, не соответствуют ожиданиям. Я обнаружил, что он округляется до даже, когда следующая цифра 5 и не может иметь никаких других цифр после этого.
Assert.AreEqual<double>(4d, Math.Round(4.5)); // Pass
Assert.AreEqual<double>(5d, Math.Round(4.6)); // Pass
Assert.AreEqual<double>(6d, Math.Round(5.5)); // Pass
Assert.AreEqual<double>(4d, Math.Round(4.500001)); // Fail - 5
Assert.AreEqual<double>(4d, Math.Round(4.45)); // Pass
Assert.AreEqual<double>(4.4, Math.Round(4.45, 1)); // Pass
Assert.AreEqual<double>(4.4, Math.Round(4.450001, 1)); // Fail - 4.5
Поведение также то же самое для Decimal.Round.
Assert.AreEqual<decimal>(4m, Decimal.Round(4.500001m)); // Fail - 5
Assert.AreEqual<decimal>(4.4m, Decimal.Round(4.450001m, 2)); // Fail - 4.5
Не следует ли при округлении учитывать только цифру, следующую непосредственно за десятичным знаком, в который вы округляете, как описано в MidpointRounding?
Операция округления принимает исходное число с неявной или заданной точностью; исследует следующую цифру, которая с такой точностью плюс один; и возвращает ближайшее число с той же точностью, что и исходное число.
1 ответ
Поведение правильное. Вы утверждаете, что 4.50001, 4.51, 4.59, 4.599999999999 должны округляться до 4. Очевидно, что цифры выше 4.5 ближе к 5, чем к 4, и поэтому должны быть округлены до 5.