Простой способ установить / сбросить отдельный бит - PullRequest
18 голосов
/ 06 августа 2010

Прямо сейчас я использую это для установки / сброса отдельных битов в байте:

if (bit4Set)
   nbyte |= (1 << 4);
else
   nbyte &= ~(1 << 4);

Но разве вы не можете сделать это более простым / элегантным способом? Как установка или сброс бита за одну операцию?

Примечание: я понимаю, что могу просто написать функцию для этого, мне просто интересно, не буду ли я заново изобретать колесо.

Ответы [ 6 ]

13 голосов
/ 06 августа 2010

Конечно!Было бы более очевидно, если бы вы расширили |= и &= в своем коде, но вы можете написать:

nbyte = (nbyte & ~(1<<4)) | (bit4Set<<4);

Обратите внимание, что bit4Set должен быть равен нулю или один - не любое ненулевое значение - чтобы это работало.

12 голосов
/ 06 августа 2010

Поместите это в функцию, тип bool установит значение 0,1 для всех битовых входов.

int change_bit(int val, int num, bool bitval)
{
    return (val & ~(1<<num)) | (bitval << num);
}
6 голосов
/ 06 августа 2010

Это совершенно разумная и полностью стандартная идиома.

5 голосов
/ 06 августа 2010

Рассматривали ли вы присвоение битам мнемоник и / или идентификаторов вместо того, чтобы ссылаться на них по номеру?

В качестве примера, скажем, установка бита 4 запускает SCRAM ядерного реактора.Вместо того, чтобы называть его «бит 4», мы назовем его «1003».Вот как может выглядеть код для этого:

int const INITIATE_SCRAM = 0x10; // 1 << 4

...

if (initiateScram) {
    nbyte |= INITIATE_SCRAM;
} else {
    nbyte &= ~INITIATE_SCRAM;
}

Это не обязательно будет более эффективным (после оптимизации), чем ваш исходный код, но я думаю, что он немного более понятен и, вероятно, более удобен в обслуживании.

2 голосов
/ 06 августа 2010

Это помечено как C ++, так что вы решили использовать std::bitset вместо того, чтобы делать все битовые манипуляции самостоятельно? Тогда вы можете просто использовать обозначение массива как: bits[3] = bit4Set, чтобы установить соответствующий бит.

0 голосов
/ 06 августа 2010
nbyte |= (1 << 4);

Если правая часть присваивания, (1 << 4), всегда является постоянной величиной, подобной этой, то это, вероятно, будет оптимизировано компилятором, поэтому будет проще в результате сборки:

mov r0, _nbyte
mov r1, 10H         ; here is the optimization, no bit shift occured
or r0, r1
st _nbyte, r0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...