Как я могу настроить поведение Math.Round в .NET? - PullRequest
0 голосов
/ 15 апреля 2011

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

7.00 -> круглый -> 7
7.50 -> круглый -> 7
7,51 -> круглый -> 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

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

Ответы [ 4 ]

2 голосов
/ 15 апреля 2011

Вы можете вычесть 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 голос
/ 15 апреля 2011

Средняя точка не может обеспечить соответствующую функциональность.Посмотрите на первую и третью строки таблицы в комментариях.Если вы измените свой 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);
        }
    }
}
0 голосов
/ 15 апреля 2011
    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
0 голосов
/ 15 апреля 2011

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

...