Как определить, установлен ли бит в позиции n в постоянной переменной?
Обнаружение, установлен ли бит (во время компиляции)
Ответы (3)
template<std::uint64_t N, std::uint8_t Bit>
struct is_bit_set
{
static bool const value = !!(N & 1u << Bit);
};
!!
используется для краткого преобразования значения в bool
и предотвращения предупреждений компилятора об усечении данных.
person
ildjarn
schedule
15.04.2011
этот ответ самый приятный на мой взгляд.
- person There is nothing we can do; 15.04.2011
int const a = 4;
int const bitset = !!((1 << 2) & a);
Теперь bitset
это 1
. Было бы 0
, если бы вы, например, сохранили 3
. Да, a
— это переменная.
person
Johannes Schaub - litb
schedule
15.04.2011
Почему бы не просто
int bitset = ((1 << 2) & a) != 0);
?
- person sharptooth; 15.04.2011
@RedX да
bitset
- это постоянное выражение. Вы можете использовать его для измерений массива, таких как int array[bitset + 1];
.
- person Johannes Schaub - litb; 15.04.2011
@Johannes, спасибо за ответ, не могли бы вы объяснить, почему это работает?
- person There is nothing we can do; 15.04.2011
@johannes Хорошо. Другой вопрос: зачем вам двойное отрицание в начале?
- person RedX; 15.04.2011
@RedX: первый приводит к
bool
(только значение 0
или 1
); второй дает действительно желаемое значение.
- person ildjarn; 15.04.2011
@RedX, потому что иначе
bitset
содержит 4
, а не 1
. @Там, en.wikipedia.org/wiki/Bitwise_operation, поиск И и битовые сдвиги.
- person Johannes Schaub - litb; 15.04.2011
@Johannes +1, так как это хороший ответ, но я соглашусь с Ильдьярном, так как он больше похож на C++.
- person There is nothing we can do; 15.04.2011
@Johnsyweb, только если у вас есть воображение;)
- person There is nothing we can do; 15.04.2011
Кроме того, мой ответ приведет к неопределенному поведению, если вы сдвинете его таким образом, что число станет отрицательным. Это справедливый выбор, так как он явно больше думал над своим ответом.
- person Johannes Schaub - litb; 15.04.2011
@Johannes Я рад, что ты согласен со мной в этом.
- person There is nothing we can do; 15.04.2011
То же самое, что предлагает пользователь ildjarn в его ответ, но с так называемым "инструмент с перечислением", который гарантирует, что компилятор выполнит все вычисления во время компиляции:
template<std::uint64_t N, std::uint8_t Bit>
struct is_bit_set
{
enum { value = ( N & (1u << Bit) ) != 0 };
};
person
sharptooth
schedule
15.04.2011
Я не думаю, что это необходимо для любого компилятора, совместимого с C++03/C++11, но в данный момент я слишком устал, чтобы копаться в стандарте. В любом случае вам, вероятно, следует изменить его на
!!(N & (1u << Bit))
, чтобы значение было строго ограничено 0
или 1
.
- person ildjarn; 15.04.2011
@ildjarn: Спасибо, я отредактировал его аналогичным образом.
- person sharptooth; 15.04.2011
const int n = 21;
,n
действительно называется переменной, даже если она не может изменяться (3/4: переменная вводится объявлением объекта). Тот факт, что терминология C++ не совсем соответствует английскому языку, — это то, к чему должны привыкнуть программисты на C++, потому что, если они этого не сделают, они в конечном итоге неправильно интерпретируют то или иное в стандарте, например, думая, что то, что сказано о переменных, не соответствует действительности. не применяется кn
, потому что это (по их мнению, но не по стандарту) константа, а не переменная. - person Steve Jessop   schedule 15.04.2011