Встроенный алгоритм .Net для округления значения до ближайшего интервала 10 - PullRequest
61 голосов
/ 08 ноября 2008

Как, в C # округлить любое значение до 10-ти интервалов? Например, если у меня 11, я хочу вернуть 10, если у меня 136, то я хочу вернуть 140.

Я легко могу сделать это вручную

return ((int)(number / 10)) * 10;

Но я ищу встроенный алгоритм для этой работы, что-то вроде Math.Round (). Причина, по которой я не хочу делать это вручную, заключается в том, что я не хочу писать одинаковый или похожий фрагмент кода во всех моих проектах, даже для чего-то более простого, как указано выше.

Ответы [ 6 ]

89 голосов
/ 08 ноября 2008

В библиотеке классов нет встроенной функции, которая будет это делать. Ближайшим является System.Math.Round () , который предназначен только для округления чисел типов Decimal и Double до ближайшего целочисленного значения. Тем не менее, вы можете заключить ваше утверждение в метод расширения, если вы работаете с .NET 3.5, что позволит вам использовать эту функцию гораздо более чисто.

public static class ExtensionMethods
{
    public static int RoundOff (this int i)
    {
        return ((int)Math.Round(i / 10.0)) * 10;
    }
}

int roundedNumber = 236.RoundOff(); // returns 240
int roundedNumber2 = 11.RoundOff(); // returns 10

Если вы программируете для более старой версии .NET Framework, просто удалите «this» из функции RoundOff и вызовите функцию следующим образом:

int roundedNumber = ExtensionMethods.RoundOff(236); // returns 240
int roundedNumber2 = ExtensionMethods.RoundOff(11); // returns 10
18 голосов
/ 08 ноября 2008

Используйте Math.Ceiling, чтобы всегда округлять вверх.

int number = 236;
number = (int)(Math.Ceiling(number / 10.0d) * 10);

Модуль (%) получает остаток, поэтому вы получаете:

// number = 236 + 10 - 6

Поместите это в метод расширения

public static int roundupbyten(this int i){
    // return i + (10 - i % 10); <-- logic error. Oops!
    return (int)(Math.Ceiling(i / 10.0d)*10); // fixed
}

// call like so:
int number = 236.roundupbyten();

выше отредактировано: я должен был пойти с моим первым инстинктом, чтобы использовать Math.Ceiling

Я писал об этом при вычислении контрольных цифр UPC .

7 голосов
/ 24 ноября 2009

Это может быть немного поздно, но я думаю, что это может быть полезно когда-нибудь ...

Я пробовал это:

public int RoundOff(int number, int interval){
    int remainder = number % interval;
    number += (remainder < interval / 2) ? -remainder : (interval - remainder);
    return number;
}

Для использования:

int number = 11;
int roundednumber = RoundOff(number, 10);

Таким образом, у вас есть возможность, будет ли половина интервала округляться в большую или меньшую сторону. =)

3 голосов
/ 08 ноября 2008

Округление числа с плавающей точкой до целого числа аналогично (int) (x + 0.5), в отличие от простого приведения x - если вам нужно кратное 10, вы можете легко адаптировать это.

Если вы просто хотите сделать целочисленную математику и округлите ее до десяти, попробуйте (x + 10/2) /10*10.

Редактировать: Я заметил, что этот ответ не соответствует запросу автора оригинала, а также является необъективной формой округления, которую я предпочитаю не делать. Однако в другом принятом ответе уже было указано, что Math.round () - гораздо лучшее решение.

1 голос
/ 24 января 2013

Старый вопрос, но здесь есть способ сделать то, что было задано, плюс я расширил его, чтобы иметь возможность округлять любое число до нужного числа сиг-фигов.

    private double Rounding(double d, int digits)
    {
        int neg = 1;
        if (d < 0)
        {
            d = d * (-1);
            neg = -1;
        }

        int n = 0;
        if (d > 1)
        {
            while (d > 1)
            {
                d = d / 10;
                n++;
            }
            d = Math.Round(d * Math.Pow(10, digits));
            d = d * Math.Pow(10, n - digits);
        }
        else
        {
            while (d < 0.1)
            {
                d = d * 10;
                n++;
            }
            d = Math.Round(d * Math.Pow(10, digits));
            d = d / Math.Pow(10, n + digits);
        }

        return d*neg;
    }


   private void testing()
   {
       double a = Rounding(1230435.34553,3);
       double b = Rounding(0.004567023523,4);
       double c = Rounding(-89032.5325,2);
       double d = Rounding(-0.123409,4);
       double e = Rounding(0.503522,1);
       Console.Write(a.ToString() + "\n" + b.ToString() + "\n" + 
           c.ToString() + "\n" + d.ToString() + "\n" + e.ToString() + "\n");
   }
1 голос
/ 06 августа 2012

Я предпочитаю не вводить библиотеку Math и не переходить к плавающей запятой, поэтому я предлагаю просто сделать целочисленную арифметику, как показано ниже, где я округляю до следующего 1К. Оберните его в метод или лямбда-фрагмент или что-то, если вы не хотите повторять.

int MyRoundedUp1024Int = ((lSomeInteger + 1023) / 1024) * 1024;

Я не проводил тесты производительности по сравнению с другими способами, но могу поспорить, что это самый быстрый способ сделать это, возможно, это версия со сдвигом и поворотом битов.

...