1 つのビットをどのように設定、クリア、トグルしますか?

ちょっと設定

ビットごとの OR 演算子 (| ) を設定します。

number |= 1UL << n;

n が設定されます number の th ビット . n 1 を設定する場合は、ゼロにする必要があります st ビットなど n-1 まで 、 n を設定する場合

1ULL を使用 number の場合 unsigned long より広いです; 1UL << n のプロモーション 1UL << n を評価するまで発生しません long の幅を超えてシフトするのは未定義の動作です。 .残りのすべての例にも同じことが当てはまります。

少しクリア

ビットごとの AND 演算子 (& ) 少しクリアします。

number &= ~(1UL << n);

n をクリアします number の th ビット .ビットごとの NOT 演算子 (~) を使用して、ビット文字列を反転する必要があります。 )、次にそれを AND します。

ちょっとトグル

XOR 演算子 (^ ) を使用してビットを切り替えることができます。

number ^= 1UL << n;

n を切り替えます number の th ビット .

ちょっと確認中

あなたはこれを求めていませんでしたが、追加したほうがよいでしょう.

ビットをチェックするには、数値 n を右にシフトしてから、ビットごとに AND します:

bit = (number >> n) & 1U;

それは n の値を入れます number の th ビット 変数 bit に .

n の変更 番目のビットから x

n の設定 番目のビットを 1 のいずれかに または 0 これは、2 の補数 C++ 実装で次のように実現できます:

number ^= (-x ^ number) & (1UL << n);

ビット n x の場合に設定されます 1 です 、x の場合はクリアされます 0 です . x の場合 他の値がある場合、ゴミが発生します。 x = !!x 0 または 1 にブーリアン化します。

これを 2 の補数の否定動作 (ここで -1 1 の補数または符号/大きさ C++ 実装とは異なり、すべてのビットが設定されている)、符号なし否定を使用します。

number ^= (-(unsigned long)x ^ number) & (1UL << n);

または

unsigned long newbit = !!x;    // Also booleanize to force 0 or 1
number ^= (-newbit ^ number) & (1UL << n);

一般に、移植可能なビット操作には符号なし型を使用することをお勧めします。

または

number = (number & ~(1UL << n)) | (x << n);

(number & ~(1UL << n)) n をクリアします 番目のビットと (x << n) n を設定します 番目のビットから x .

また、一般的にコードをコピーして貼り付けないことも一般的に良い考えであり、非常に多くの人がプリプロセッサ マクロ (コミュニティ wiki の回答のように) や何らかのカプセル化を使用しています。


標準 C++ ライブラリの使用:std::bitset<N> .

または Boost バージョン:boost::dynamic_bitset .

自分でロールする必要はありません:

#include <bitset>
#include <iostream>

int main()
{
    std::bitset<5> x;

    x[1] = 1;
    x[2] = 0;
    // Note x[0-4]  valid

    std::cout << x << std::endl;
}
[Alpha:] > ./a.out
00010

Boost バージョンでは、標準ライブラリのコンパイル時サイズのビットセットと比較して、実行時サイズのビットセットを使用できます。


もう 1 つのオプションは、ビット フィールドを使用することです:

struct bits {
    unsigned int a:1;
    unsigned int b:1;
    unsigned int c:1;
};

struct bits mybits;

3 ビット フィールドを定義します (実際には、3 つの 1 ビット フィールドです)。ビット操作が少し (笑) 簡単になりました:

ビットを設定またはクリアするには:

mybits.b = 1;
mybits.c = 0;

少し切り替えるには:

mybits.a = !mybits.a;
mybits.b = ~mybits.b;
mybits.c ^= 1;  /* all work */

少し確認:

if (mybits.c)  //if mybits.c is non zero the next line below will execute

これは、固定サイズのビット フィールドでのみ機能します。それ以外の場合は、以前の投稿で説明されているビットをいじる手法に頼る必要があります。