Как я могу настроить поведение Math.Round.Round в .NET?

#.net #vb.net #math #rounding

#.net #vb.net #математика #округление

Вопрос:

Я должен использовать метод round, который следует этому поведению:

7.00 -> round -> 7
7.50 -> round -> 7
7.51 -> round -> 8

Я пытался использовать Math.Round, но это работает немного по-другому.

 Dim val As Decimal = 7.5
Dim a As Decimal = Math.Round(val, 0) ' -> 8
Dim b As Decimal = Math.Round(val, 0, MidpointRounding.AwayFromZero) ' -> 8
Dim c As Decimal = Math.Round(val, 0, MidpointRounding.ToEven) ' -> 8
  

Как я могу реализовать свою логику округления?

Комментарии:

1. Итак, вы хотите, чтобы все варианты X.5 были равны X? Стандартом для C # является то, что если значение равно X.5, оно округляется до ближайшего четного числа. Таким образом, и 7.5, и 8.5 будут округлены до 8.

2. Кстати, ваш код написан на VB, а не на C#

3. почему вы пометили этот вопрос как C # (в обоих тегах и названии), но опубликовали код на VB?

4. Простой ответ: способ, которым вы хотите выполнить округление, неверен. Это не соответствует никакому стандартному соглашению и поэтому довольно бесполезно. Платформа .NET Framework предоставляет вам две общепринятые формы: AwayFromZero (также известную как то, чему вы учились в школе) и ToEvent (также известную как округление «Банкира»). Подробности в документации .

5. Извините, я испортил проект code… Я разработчик на C # и VB … и иногда это сводит меня с ума 🙂 Однако я знаю, что это не стандартное поведение, но есть особый случай, в котором это необходимо сделать.

Ответ №1:

Вы могли бы вычесть 0.01 из общего числа, а затем вызвать Math.round(..) .

 double d = 7.5;
double result = Math.Round(d - 0.01);
  

Если число отрицательное, вам нужно будет сделать следующее, чтобы получить тот же результат:

 double d = -7.5;
if (d < 0)
{
    double tmp = Math.Abs(d) - 0.01;
    double result = -Math.Round(tmp);
}
  

Вот рабочий пример.

Однако обратите внимание, что это поведение, вероятно, не то, чего вы хотите, как отметили несколько других.

Если вы читали комментарии к этому ответу, @alex zhevzhik также отметил, что это решение завершится неудачей, если входные данные будут содержать более 2 десятичных знаков.

Комментарии:

1. И что делает ваше решение, когда число отрицательное?

2. Как насчет округления 7.50000009? Ваше решение округлит его до 7.0, между тем все указывает на то, что правильный ответ равен 8.0

3. @alex zhevzhik: Вы правы, но пример, приведенный LukePet, не предполагает, что он столкнется с таким числом.

Ответ №2:

Midpoint не удалось обеспечить соответствующую функциональность. Взгляните на первую и третью строки в таблице в примечаниях. Если вы измените значение val на 6.5, вы получите ожидаемое поведение, но не с 7.5.

Вы должны написать свою собственную реализацию такого округления.

Реализация Джаведа Акрама хороша, но она работает совершенно неправильно с отрицательными числами. Поскольку вы не предоставили подробностей округления отрицательных чисел, я полагаю, что стандартное округление подходит. Кроме того, вы должны учитывать «специальные» двойные значения:

 static class Helper
{
    public static double Round(double val)
    {
        if (Double.IsNaN(val) || Double.IsNegativeInfinity(val) || Double.IsPositiveInfinity(val))
        {
            return val;
        }

        var decimalPart = Math.Truncate(val);
        if (val >= 0)
        {
            if (val - decimalPart <= 0.5)
            {
                return Math.Floor(val);
            }
            else
            {
                return Math.Ceiling(val);
            }
        }
        else
        {
            return Math.Round(val, 0);
        }
    }
}
  

Ответ №3:

Ну, я не знаю, существует ли математика.Метод Round, который делает то, что вы хотите, но я думаю, вам нужно будет написать свой собственный. Потому что обычно 7.5 округляется до 8, если только я не забыл все, чему научился в средней школе.

Ответ №4:

     Dim i As Decimal
    Dim j As Integer
    Dim k As Decimal

    i = 7.51
    k = i - Math.Truncate(i)  'decimal part of number

    If (k <= 0.5) Then
        j = Math.Floor(i)
    Else
        j = Math.Ceiling(i)
    End If