#c #bit-manipulation #bitwise-operators
#c #битовая манипуляция #побитовые операторы
Вопрос:
Каков наилучший способ заполнить переменную неизвестным (во время компиляции) количеством единиц? Например, скажем:
int n = 5;
int b = fillwithones(5);
теперь b содержит 11111 (в двоичном формате).
Я не могу просто жестко закодировать int b = 31, потому что n заранее неизвестно (в моем приложении).
Я мог бы сделать что-то вроде этого:
int b = pow(2, n) - 1
Но использование pow кажется очень расточительным.
Спасибо!
Ответ №1:
Вы можете использовать сдвиг влево, а затем вычесть 1:
unsigned int b = (1U << n) - 1U;
// Broken down into steps
// 1 = 00000001b
// 1 << 5 = 00100000b
// (1 << 5) - 1 = 00011111b
Причина, по которой это работает, заключается в том, что 1 сдвиг влево n раз совпадает с 2 n, поскольку каждая единственная позиция бита представляет степень 2.
Комментарии:
1. Лучше всего использовать
unsigned
вместоint
этого.2. @TomZych: был в процессе этого исправления, вы быстры, сэр 😉
3.Я бы выбрал
unsigned long long
(-1ULL >> (sizeof (unsigned long long) - n)
, но постоянное сворачивание в любом случае даст тот же результат.4.
n
я думаю, @Alex здесь не является постоянным; Кстати, умножьтеsizeof
на 8 (CHAR_BIT
)
Ответ №2:
Забавный способ получить старшие биты равными 1, а младшие биты равными нулю — использовать этот приятный трюк:
#include <limits.h>
...
int b = INT_MIN >> n;
Это работает, потому что операция сдвига влево для отрицательного числа сохранит знак операции, а поскольку INT_MIN равно 10000 ….0000, сдвиг его на n влево даст вам n бит до 1, но с другой стороны.