C быстрый расчет следующего кратного 4?

Что такое быстрый способ округлить unsigned int до кратного 4 ?

У кратного 4 есть два младших значащих бита 0, правильно? Поэтому я мог бы замаскировать их, а затем сделать оператор switch, добавив либо 1,2, либо 3 к данному uint .

Это не очень изящное решение.

Существует также арифметическое округление:

  myint == 0 ? 0 : ((myint+3)/4)*4 

Наверное, есть лучший способ, включая некоторые битовые операции?

 (myint + 3) & ~0x03 

Добавление 3 состоит в том, что следующий кратный 4 становится прежним кратным 4, который создается посредством операции по модулю, выполненной путем маскировки, поскольку делитель является степенью 2.

Я предполагаю, что то, что вы пытаетесь достичь, – это выравнивание входного числа, т. Е. Если исходный номер уже кратен 4, то его не нужно менять. Однако это не ясно из вашего вопроса. Может быть, вам нужно следующее несколько, даже если исходный номер уже несколько? Просьба уточнить.

Чтобы выровнять произвольное неотрицательное число i на произвольной границе n вам просто нужно сделать

 i = i / n * n; 

Но это приведет его к отрицательной бесконечности. Чтобы выровнять его с положительной бесконечностью, добавьте n - 1 до формирования выравнивания

 i = (i + n - 1) / n * n; 

Это уже достаточно хорошо для всех целей и задач. В вашем случае это будет

 i = (i + 3) / 4 * 4; 

Однако, если вы предпочтете выжать из него несколько процессорных часов, вы можете использовать тот факт, что i / 4 * 4 можно заменить бит-twiddling i & ~0x3 , что i & ~0x3 вам

 i = (i + 3) & ~0x3; 

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

Если «next multiple of 4» означает наименьшее кратное 4, которое больше вашего значения unsigned int myint, тогда это будет работать:

 (myint | 0x03) + 1; 

(myint + 4) & 0xFFFC

Если вы хотите, чтобы следующий кратный 4 строго больше, чем myint , это решение будет делать (аналогично предыдущим сообщениям):

 (myint + 4) & ~3u 

Если вы хотите округлить до ближайшего кратного 4 (оставляя myint без изменений, если он кратен 4), это должно работать:

 (0 == myint & 0x3) ? myint : ((myint + 4) & ~3u); 

Это не зависит от ветки, обычно настраивается, легко понимается (если вы знаете о байтовых строках C), и это позволяет вам не думать о размере бита myInt:

 myInt += "\x00\x03\x02\x01"[myInt & 0x3]; 

Единственным недостатком является возможный доступ к одной памяти в другом месте (статическое хранилище строк), чем стек.

myint = (myint + 4) & 0xffffffc

Это предполагает, что с помощью «следующего кратного 4» вы всегда двигаетесь вверх; т. е. 5 -> 8 и 4 -> 8.