Предлагаемое решение проблемы округления (для отчетности):
private double RoundedResult(double v, int digits)
{
// return Math.Round(value, digits);
// sometimes does not do proper rounding per user feedback
// proposed fix relies on a fixed decimal (F) format rendering converted back to double
return
Convert.ToDouble
(
v.ToString("F"+digits);
);
}
Я не уверен относительно капризов формата F n .
Вопрос: Является ли вышеуказанное разумным решением?и может ли это вызвать другие проблемы позже?
Справочная информация
В отдельном отчете будет <1000 округленных чисел, поэтому я не беспокоюсь о производительности. </p>
Я работаю с устаревшей системой, использующей код приложения SQL Server и ASP NET MVC.Значения данных double?
, а значения должны быть округлены до различного числа десятичных знаков для отчетности.Я знаю, что система должна использовать десятичные значения данных вместо double, но я застрял с унаследованным double.
Конечный пользователь жаловался на эту конкретную ситуацию (и другие подобные):
Файл текстовых данных имеет 0,000065, средство просмотра базы данных показывает 0,000065, а в отчете (до 5 десятичных знаков) отображается 0,00006 вместо 0,00007.Отчетность всегда должна округляться.
Информация о текстовом файле:
Я работаю с особенностями
double? value = 0.000065;
Я знаю, что 0.000065d
должно быть немного меньше 0.000065m
:
Math.Round(value.Value,5,...)
возвращает 0.00006
, используя MidpointRounding.AwayFromZero
и ToEven
. - Отладчик показывает
0.000065d-0.000065f
as -1.7695129487117073E-13 double
- Один бросок значения округляется, часы отладчика показывают
Math.Round((Single)value,5) 7E-05 double
Слегка озадачивает
value.Value.ToString("F5")
возвращает "0.00007"
Я не знаю, выполняет ли F5
какое-либо внутреннее приведение, но результат соответствует округлению одиночного приведения,* В 1064 * (он же String.Format()
) происходит какое-то mojo.
Одиночный случай округления одиночного броска двойного 0,000065 «сработало» с получением 0,0007, но, вероятно, не во всех случаях.
Код скрипты
Я написал .NET Fiddle , чтобы выполнить итерацию по большому количеству случаев, заканчивающихся в 5, и кажется,этот ToString («F5») всегда давал «ожидаемый человеком» результат.