web-dev-qa-db-ja.com

個々のビットを設定/設定解除する簡単な方法

現在、これを使用して、バイト内の個々のビットを設定/設定解除しています。

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

しかし、もっとシンプルでエレガントな方法でそれを行うことはできませんか? 1回の操作でビットを設定または設定解除するのが好きですか?

注:私はそれを行うための関数を書くことができることを理解しています。私は車輪の再発明をしないのではないかと思っています。

18
djeidot

承知しました!コードで|=&=を展開すると、より明白になりますが、次のように書くことができます。

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

これが機能するには、bit4Setがゼロまたはone —ゼロ以外の値ではない—である必要があることに注意してください。

13
Pascal Cuoq

関数に入れると、bool型はすべてのbitval入力に0,1を適用します。

int change_bit(int val, int num, bool bitval)
{
    return (val & ~(1<<num)) | (bitval << num);
}
12

これは完全に賢明で完全に標準的なイディオムです。

6
Alexandre C.

ニーモニックや識別子を番号で参照するのではなく、ビットに割り当てることを検討しましたか?

例として、ビット4を設定すると原子炉SCRAMが開始されるとします。これを「ビット4」と呼ぶ代わりに、INITIATE_SCRAMと呼びます。このためのコードは次のようになります。

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

...

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

これは(最適化後)元のコードよりも必ずしも効率的であるとは限りませんが、少し明確で、おそらく保守性が高いと思います。

5
Dan Moulding

これはC++としてタグ付けされているので、すべてのビット操作を自分で行う代わりにstd::bitsetを使用することを検討しましたか?次に、配列表記をbits[3] = bit4Setとして使用して、適切なビットを設定できます。

2
Mark B
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
0
Donotalo