Я использую побитовое для включения и выключения битов следующим образом:
unsigned char myChar = ...some value
myChar |= 0x01 << N // turn on the N-th bit
myChar &= ~(0x01 << N) //turn off the N-th bit
Теперь предположим, что значение N известно, но операция установки/снятия зависит от значения бита другого беззнакового символа. С этого момента я делаю так:
if ((otherChar & (0x01 << M)) != 0)
{
//M-th bit of otherChar is 1
myChar |= 0x01 << N;
}else
{
myChar &= ~(0x01 << N);
}
Это должна быть своего рода операция "перемещения бита" из беззнакового символа в другой.
Мой вопрос: есть ли способ сделать это без использования условного? (и без std::bitset тоже)
Ответ 1 · рейтинг 3 · Jerry Coffin
Краткий ответ - да".
Более длинный ответ заключается в том, что вы используете бит непосредственно из источника:
unsigned char bit = 1 << N;
myChar &= ~bit; // Zero the bit without changing anything else
myChar |= otherChar & bit; // copy the bit from the source to the destination.
Это предполагает, что вы хотите скопировать бит N из источника в бит N адресата. Если биты источника и назначения могут иметь разные смещения, все становится немного сложнее. Вы должны не только извлечь правильный бит из источника, но затем вам нужно переместить его в правильное место, а затем ИЛИ в место назначения. Основная идея примерно такая же, как и выше, но код для переключения немного утомителен. Проблема в том, что вы хотите сделать что-то вроде:
unsigned char temp = source & 1 << M;
temp <<= N - M;
dest |= temp;
Это будет работать нормально, если N> M, но если M> N, вы получите что-то вроде temp <<= -3;. Вам хотелось бы, чтобы сдвиг влево на -3 превратился в сдвиг вправо на 3, но это не то, что происходит, поэтому вам нужен некоторый условный код, чтобы получить абсолютное значение и выяснить, нужно ли сделать сдвиг вправо или влево, чтобы получить бит от источника в правильное место в месте назначения.
Ответ 2 · рейтинг 3 · Oliver Charlesworth
Одно из решений состоит в том, чтобы сначала всегда сбрасывать бит, а затем побитово или в соответственно смещенной и замаскированной версии otherChar.
Ответ 3 · рейтинг 3 · Mark Tolonen
Это читает бит from c1 и записывает его в бит to c2.
#include <stdio.h>
typedef unsigned char uchar;
uchar move_bit(uchar c1, int from, uchar c2, int to)
{
int bit;
bit = (c1 >> from) & 1; /* Get the source bit as 0/1 value */
c2 &= ~(1 << to); /* clear destination bit */
return (uchar)(c2 | (bit << to)); /* set destination bit */
}
int main()
{
printf("%02X\n",move_bit(0x84,3,0x42,5));
printf("%02X\n",move_bit(0x81,0,0x03,7));
printf("%02X\n",move_bit(0xEF,4,0xFF,6));
return 0;
}
Результат:
42
83
BF