Подтвердить что ты не робот

Измените бит целого числа

Мы имеем целое число

int x = 50;

в двоичном формате, это

00110010

Как я могу изменить четвертый (4-й) бит программно?

4b9b3361

Ответ 1

Вы можете установить четвертый бит числа с помощью OR-ing со значением, равным нулю всюду, кроме четвертого. Это можно сделать как

x |= (1u << 3);

Аналогичным образом, вы можете очистить четвертый бит, используя AND, со значением, которое является везде, кроме четвертого. Например:

x &= ~(1u << 3);

Наконец, вы можете переключить четвертый бит с помощью XOR-ing со значением, равным нулю всюду, кроме четвертого бита:

x ^= (1u << 3);

Чтобы понять, почему это работает, нам нужно посмотреть на две вещи:

  • Каково поведение оператора << в этом контексте?
  • Каково поведение операторов AND, OR и XOR здесь?

Во всех трех приведенных выше фрагментах кода мы использовали оператор << для генерации значения. Оператор << является побитовым сдвигом-левым оператором, который принимает значение, а затем сдвигает все его биты на несколько шагов влево. В вашем случае я использовал

1u << 3

принять значение 1 (которое имеет двоичное представление 1) и затем сдвинуть все его биты на три точки, заполнив недостающие значения с помощью 0. Это создает двоичное значение 1000, которое имеет бит, установленный в четвертый бит.

Теперь, почему

x |= (1u << 3);

установить четвертый бит числа? Это связано с тем, как работает оператор OR. Оператор |= похож на += или *=, за исключением побитового ИЛИ, что эквивалентно

x = x | (1u << 3);

Итак, почему OR-ing x с двоичным значением 1000 устанавливает свой четвертый бит? Это связано с тем, как определяется OR:

0 | 0  == 0
0 | 1  == 1
1 | 0  == 1
1 | 1  == 1

Что еще более важно, мы можем переписать это более компактно, так как

x | 0  == x
x | 1  == 1

Это чрезвычайно важный факт, потому что это означает, что OR-ing любой бит с нолем не изменяет значение бита, тогда как OR-ing любой бит с 1 всегда устанавливает бит в один. Это означает, что когда мы пишем

x |= (1u << 3);

поскольку (1u < 3) представляет собой значение, равное нулю всюду, кроме четвертого бита, побитовое ИЛИ оставляет все биты x неизмененными, за исключением четвертого бита, который затем устанавливается равным единице. В более общем случае, OR-число с значением, которое представляет собой серию нулей и единиц, сохранит все значения, в которых бит равен нулю, и установите все значения, в которых бит равен единице.

Теперь посмотрим

x &= ~(1u << 3);

Здесь используется оператор побитового дополнения ~, который принимает число и переворачивает все его биты. Если мы предположим, что целые числа представляют собой два байта (просто для простоты), это означает, что фактическое кодирование (1u << 3) равно

0000000000001000

Когда мы возьмем дополнение к этому, получим число

1111111111110111

Теперь посмотрим, что произойдет, когда мы побитовое и два значения вместе. Оператор И имеет эту интересную таблицу истинности:

0 & 0   == 0
0 & 1   == 0
1 & 0   == 0
1 & 1   == 1

Или, более компактно:

x & 0   == 0
x & 1   == x

Обратите внимание, что это означает, что если мы и два числа вместе, результирующее значение будет таким, чтобы все биты AND-ed с нулем были установлены на ноль, а все остальные биты сохранялись. Это означает, что если мы И с

~(1u << 3)

мы имеем AND с

1111111111110111

Таким образом, в соответствии с нашей таблицей, это означает "сохранить все биты, кроме четвертого бита, как есть, а затем изменить четвертый бит на нуль".

В более общем плане, если вы хотите очистить набор битов, создайте число, которое есть везде, где вы хотите сохранить биты без изменений, и ноль, где вы хотите очистить бит.

Наконец, давайте посмотрим, почему

x ^= (1u << 3)

Отбрасывает четвертый бит числа. Это связано с тем, что бинарный оператор XOR имеет эту таблицу истинности:

0 ^ 0  == 0
0 ^ 1  == 1
1 ^ 0  == 1
1 ^ 1  == 0

Обратите внимание, что

x ^ 0  == 0
x ^ 1  == ~x

Где ~x противоположно x; это 0 для 1 и 1 для 0. Это означает, что если мы XOR x со значением (1u << 3), мы XOR-ing с

0000000000001000

Таким образом, это означает "сохранить все биты, но четвертый бит установлен как есть, но переверните четвертый бит". В более общем плане, если вы хотите перевернуть некоторое количество бит, XOR - это значение с числом, которое имеет нулевое значение, где вы хотите сохранить биты целыми, и тот, где вы хотите перевернуть эти биты.

Надеюсь, это поможет!

Ответ 2

Вы всегда можете использовать std::bitset, что упрощает модификацию бит.

Или вы можете использовать манипуляции с битами (при условии, что вы имеете в виду 4-й бит, подсчитывающий один. Не вычитайте 1, если вы имеете в виду подсчет от 0). Обратите внимание, что я использую 1U только для того, чтобы гарантировать, что вся операция будет выполняться в неподписанных числах:

Чтобы установить: x |= (1U << (4 - 1));

Чтобы очистить: x &= ~(1U << (4 - 1));

Для переключения: x ^= (1U << (4 - 1));

Ответ 3

Чтобы установить четвертый бит, OR с 00001000 (двоичным).

Чтобы очистить четвертый бит, AND с помощью 11110111 (двоичный).

Чтобы переключить четвертый бит, XOR на 00001000 (двоичный).

Примеры:

00110010 ИЛИ 00001000 = 00111010

00110010 И 11110111 = 00110010

00110010 XOR 00001000 = 00111010

Ответ 4

Попробуйте одну из этих функций на языке C изменить n бит

char bitfield;

// start at 0th position

void chang_n_bit(int n, int value)
{
    bitfield = (bitfield | (1 << n)) & (~( (1 << n) ^ (value << n) ));
}

void chang_n_bit(int n, int value)
{
    bitfield = (bitfield | (1 << n)) & ((value << n) | ((~0) ^ (1 << n)));
}

void chang_n_bit(int n, int value)
{
    if(value)
        bitfield |= 1 << n;
    else
        bitfield &= ~0 ^ (1 << n);
}

char print_n_bit(int n)
{
    return (bitfield & (1 << n)) ? 1 : 0;
}

Ответ 5

Просто, так как у вас есть или какое бы то ни было значение,

int x = 50;

Чтобы программно выбрать 4-й бит (справа),

int y = x | 0x00000008;

Ответ 6

Вы можете использовать двоичные И и ИЛИ для переключения четвертого бита.

Чтобы установить четвертый бит в x, вы должны использовать x |= 1<<3;, 1<<3 как левый сдвиг 0b0001 на три бита, производящий 0b1000.

Чтобы очистить четвертый бит от x, вы должны использовать x &= ~(1<<3);, двоичный И между 0b00110010 (x) и (эффективно) 0b11110111, маскирующий каждый бит в x, который не находится в четвертом положении, тем самым очистив его.