Встроенный алгоритм .Net для округления значения до ближайших 10 интервалов

Asked
Viewd72300

68

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

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

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

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

6 ответов

102

В библиотеке классов нет встроенной функции, которая бы это сделала. Ближайшим из них является 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, просто удалите "this" из функции RoundOff и вызовите функцию следующим образом:

 int roundedNumber = ExtensionMethods.RoundOff(236); // returns 240
int roundedNumber2 = ExtensionMethods.RoundOff(11); // returns 10
 
  • Собственно запустить. Вот исходный код (включая тестовый класс) и даже сборка исходного кода. Работает, и правильно. http://labs.coldacid.net/code/number-rounding-extension-method

    Chris Charabaruk03 марта 2009, 15:34
  • Кроме того, вы изменили 10 на 10.0, о чем полезно знать, иначе он не будет компилироваться.

    Dave Van den Eynde03 марта 2009, 16:09
  • А, но вы в оригинальном ответе вообще не использовали Math.Round ().

    Dave Van den Eynde03 марта 2009, 16:01
  • Он все равно не вернет 240, потому что вы округляете в меньшую сторону.

    Dave Van den Eynde03 марта 2009, 11:56
  • С этим кодом связано множество проблем, а именно: он не компилируется (отсутствует тип возвращаемого значения) и не округляется до ближайшего. В вашем примере он возвращает 230 и 10.

    Dave Van den Eynde03 марта 2009, 08:43
21

Используйте 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 .

  • Попробуйте с 240. Что вы получите? Или, если на то пошло, 11.

    Chris Charabaruk08 ноября 2008, 06:54
10

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

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

 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);
 

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

4

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

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

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

  • Должен сказать, что, несмотря на то, что я часто использовал этот трюк, Math.Round выглядит намного чище.

    Dave Van den Eynde03 марта 2009, 16:02