Методология Math.Round, начиная с наименьшего десятичного знака

Было много потоков, запущенных из-за путаницы в том, как работает Math.Round . По большей части на них отвечают, подсказав людям параметр MidpointRounding , и что большинство людей ожидают MidpointRounding.AwayFromZero . У меня есть еще один вопрос относительно фактического алгоритма, реализованного AwayFromZero.

Учитывая следующее число (результат ряда вычислений): 13. 398749999999999999999999999M

наши пользователи ожидают увидеть тот же результат, что Excel даст им 13.39875 . Поскольку в настоящее время они округляют это число до 4, используя Math.Round (num, 4, MidpointRounding.AwayFromZero), результат будет на 0,0001 меньше ожидаемого. Предположительно, причина этого в том, что алгоритм просто смотрит на пятую цифру (4), а затем округляет соответственно. Если бы вы начали округлять последние 9, реальный математический ответ фактически дал бы вам то же число, что и в Excel.

Итак, вопрос в том ... есть ли способ эмулировать это поведение, а не текущее?

Я написал рекурсивную функцию, которую мы могли бы использовать тем временем. Но прежде чем мы запустили его в производство, я хотел посмотреть, что SO думает о проблеме: -)

    private decimal Round(decimal num, int precision)
    {
        return Round(num, precision, 28);
    }

    private decimal Round(decimal num, int precision, int fullPrecision)
    {
        if (precision >= fullPrecision) return Math.Round(num, precision);

        return Round(Math.Round(num, fullPrecision), precision, --fullPrecision);
    }

Редактировать: просто для ясности, Я должен был быть более ясным в моем первоначальном посте. Спрашиваемая здесь методология округления заключается в том, что меня представляют бизнес-аналитики и пользователи, которые сообщают о «ошибке округления». Несмотря на то, что мне неоднократно говорили, что это не неправильно, просто отличается от того, что они ожидают ... этот отчет продолжает поступать. Так что я просто собираюсь ограничиться сбором данных, чтобы собрать как можно больше информации по этой теме, чтобы сообщить о ней пользователи.

В этом случае, похоже, что любая другая система, используемая для генерации этих средних цен (которые мы должны сопоставить), использует другую точность уровня (10 в базе данных, и Excel, по-видимому, по умолчанию равен 15 или около того) , Учитывая, что у всех разный уровень точности, я застрял в середине с вопросом о переходе на более низкую точность, некоторые странные правила округления (как описано выше) или просто результаты, отличные от ожидаемых пользователями.

7
задан Charles 7 September 2011 в 00:32
поделиться

2 ответа

Если я вас правильно понял, люди ожидают 13,3988, потому что они сначала округляют до 13,39875, а затем до 13,3988, и им нужно, чтобы вы были совместимы с ошибками.

Если это так, то нет необходимости повторять дальше, чем один шаг округления, так как изъян в их методе проявляется только на последнем шаге округления (по своей природе округление сводит на нет значение шага за два шага до него). ).

private static decimal InaccurateRound(decimal num, int precision)
{
  return Math.Round(
    Math.Round(num, precision + 1, MidpointRounding.AwayFromZero),
    precision, MidpointRounding.AwayFromZero);
}
3
ответ дан 7 December 2019 в 09:55
поделиться

Так что, если вы округлите это число до 5 знаков, а затем округлите результат до 4 знаков... Вы получите другой результат, чем если бы вы просто округли исходное число до 4 знаков? Это ожидаемо. И я думаю, это объясняет, что вам нужно делать. другой вариант - заставить Excel показывать полную точность, чтобы «они» округлялись так же, как ваш код. Округление дважды просто кажется неправильным.

3
ответ дан 7 December 2019 в 09:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: