быстрое увеличение числа будет мод 16 в C - PullRequest
4 голосов
/ 05 июня 2011

Каков наилучший способ получить ближайшее, не меньшее число, которое делится на 16?

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

int non_smaller_int_divisible_by_16(int x)
{
  return x + ((16 - (x % 16)) % 16);
}

ожидаемые результаты:

result | X values
-------|----------
16     | 1,2,..., 16
32     | 17, 18, ... 32
48     | 33, 34, ..., 48

и т. Д.

Ответы [ 4 ]

11 голосов
/ 05 июня 2011
int non_smaller_int_divisible_by_16(int x)
{
  return (x + 15) & ~15;
}

Поскольку 16 - это степень двойки, вы можете использовать двоичную маскировку - прибавьте 15, чтобы мы получили следующее наивысшее кратное, и замаскируйте битовой инверсией 15, чтобы очистить нижние биты.

Редактировать:

Непонятно, что вы хотите получить с отрицательными числами - и ваш, и мой код будут округляться до более положительных значений (т. Е. Отрицательные числа будут уменьшаться).Если отрицательные значения не имеют смысла в вашей программе, было бы лучше использовать тип без знака.

Наконец, вам может быть интересно взглянуть на Bit Twiddling Hacks , которыйбольшая коллекция некоторых действительно умных (хотя часто чрезвычайно неясных) трюков в этом направлении.

5 голосов
/ 05 июня 2011

@ решение оттуда более элегантно и быстрее, но если вам нужно сделать это с числом, не равным 2, тогда вы можете использовать этот подход.

int non_smaller_int_divisible_by_n(int x, int n)
{
  return n*((x+n-1)/n);
}
1 голос
/ 06 июня 2011

после комментария @ nemo, есть отличный способ решить эту проблему, который работает для всех модов, очень читабелен, и должен быть быстрым

unsigned int non_smaller_int_divisible_by_16(unsigned int x)
{
   return x + ((-x) % 16);
}

поэтому общая версия

unsigned int non_smaller_int_divisible_by_base(unsigned int x, unsigned int base)
{
   return x + ((-x) % base);
}
0 голосов
/ 05 июня 2011
int non_smaller_int_divisible_by_16(int x) {
    return (x & 15) ? (x | 15) + 1 : x;
}
...