Согласно документации, метод decimal.Round
использует округление до четности алгоритм, который не является обычным для большинства приложений. Поэтому я всегда заканчиваю тем, что пишу специальную функцию, чтобы сделать более естественный алгоритм округления до половины:
public static decimal RoundHalfUp(this decimal d, int decimals)
{
if (decimals < 0)
{
throw new ArgumentException("The decimals must be non-negative",
"decimals");
}
decimal multiplier = (decimal)Math.Pow(10, decimals);
decimal number = d * multiplier;
if (decimal.Truncate(number) < number)
{
number += 0.5m;
}
return decimal.Round(number) / multiplier;
}
Кто-нибудь знает причину этого решения по дизайну фреймворка?
Есть ли в фреймворке встроенная реализация алгоритма округления до половины? Или, может быть, какой-то неуправляемый Windows API?
Новичков могут ввести в заблуждение, если они просто пишут decimal.Round(2.5m, 0)
, ожидая 3 в результате, но вместо этого получая 2.
0.5.ToString("0") == "1"
). Я думаю, что обычно при округлении вы делаете это для отображения значения на экране. Так что это делает его действительно интересным. - person Matthijs Wessels   schedule 05.09.2012d = 9.825m
- этоDecimal
(точно представляемый точно), то такие вещи, какdecimal.Round(d, 2)
иMath.Round(d, 2)
, дают9.82
, а форматирование, такое какd.ToString("F2")
,d.ToString("N2")
иd.ToString("0.00")
, дает"9.83"
(десятичный разделитель в зависимости от языка и региональных параметров текущего потока). Не дружелюбный. - person Jeppe Stig Nielsen   schedule 27.09.2012Math.Round
. - person Matthijs Wessels   schedule 27.09.2012