web-dev-qa-db-ja.com

整数のビットを変更します

整数があります

int x = 50;

バイナリでは、

00110010

4番目(4番目)のビットをプログラムで変更するにはどうすればよいですか?

31
pedram

数値の4番目のビットは、4番目のビットを除くすべての場所でゼロになる値とOR演算することで設定できます。これは次のように行うことができます

_x |= (1u << 3);
_

同様に、4番目のビットを除くANDは、4番目のビットを除くすべての場所で1である値でクリアできます。例えば:

_x &= ~(1u << 3);
_

最後に、4番目のビットを除くすべての場所でゼロの値でXORすることにより、4番目のビットを切り替えることができます。

_x ^= (1u << 3);
_

これが機能する理由を確認するには、次の2つを調べる必要があります。

  1. このコンテキストでの_<<_演算子の動作は何ですか?
  2. ここで、AND、OR、およびXOR演算子の動作は何ですか?

上記の3つのコードスニペットすべてで、_<<_演算子を使用して値を生成しました。 _<<_演算子はビット単位の左シフト演算子であり、値を取得してから、すべてのビットを数ステップ左にシフトします。あなたの場合、私は

_1u << 3
_

値1(バイナリ表現1)を取得し、すべてのビットを3つのスポットにシフトして、欠損値を0で埋めます。これにより、4番目にビットが設定されたバイナリ値_1000_が作成されます。ビット。

さて、なぜ

_x |= (1u << 3);
_

数値の4番目のビットを設定しますか?これは、OR演算子の動作方法と関係があります。 _|=_演算子は、ビット単位のORを除き、_+=_または_*=_に似ています-これは次と同等です

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

では、なぜバイナリ値_1000_とxのOR演算を行うと4番目のビットが設定されるのでしょうか?これは、ORの定義方法に関係しています。

_0 | 0  == 0
0 | 1  == 1
1 | 0  == 1
1 | 1  == 1
_

ただし、もっと重要なことは、これをよりコンパクトに書き換えることができることです。

_x | 0  == x
x | 1  == 1
_

これは非常に重要な事実です。これは、ビットを0とOR結合してもビットの値が変更されず、ビットを1とOR結合すると常にそのビットが1に設定されるためです。これは、私たちが書くとき

_x |= (1u << 3);
_

(1u << 3)は4番目のビットを除いてどこでもゼロであるため、ビット単位のORは、4番目のビットを除いてxのすべてのビットを変更しないままにします。より一般的には、一連のゼロと1の値で数値をOR演算すると、ビットがゼロのすべての値が保持され、ビットが1のすべての値が設定されます。

さて、見てみましょう

_x &= ~(1u << 3);
_

これは、ビット単位の補数演算子_~_を使用します。これは、数値を取り、すべてのビットを反転します。整数が2バイトであると仮定すると(単純にするため)、これは_(1u << 3)_の実際のエンコードが

_0000000000001000
_

これを補完すると、数が得られます

_1111111111110111
_

次に、2つの値をビット単位でAND結合するとどうなるかを見てみましょう。 AND演算子には、次の興味深い真理値表があります。

_0 & 0   == 0
0 & 1   == 0
1 & 0   == 0
1 & 1   == 1
_

または、よりコンパクトに:

_x & 0   == 0
x & 1   == x
_

これは、2つの数値をAND結合すると、結果の値は、ANDされたすべてのビットがゼロに設定され、他のすべてのビットが保持されることを意味することに注意してください。これは、かつAND

_~(1u << 3)
_

私たちはAND-ingです

_1111111111110111
_

したがって、上の表では、これは「4番目のビットを除くすべてのビットをそのままにして、4番目のビットをゼロに変更する」ことを意味します。

より一般的には、ビットのセットをクリアしたい場合は、ビットを変更せずに維持したいすべての場所で1、ビットをクリアしたい場所でゼロの数を作成します。

最後に、理由を見てみましょう

_x ^= (1u << 3)
_

数値の4番目のビットを反転します。これは、バイナリXOR演算子に次の真理値表があるためです。

_0 ^ 0  == 0
0 ^ 1  == 1
1 ^ 0  == 1
1 ^ 1  == 0
_

に注意してください

_x ^ 0  == 0
x ^ 1  == ~x
_

ここで_~x_はxの反対です。これは、1が0で、0が1です。これは、値_(1u << 3)_を持つXOR xの場合、それをXORすることを意味します。

_0000000000001000
_

したがって、これは「4番目のビット以外のすべてのビットはそのままにして、4番目のビットを反転させる」ことを意味します。より一般的には、いくつかのビットを反転する場合は、ビットをそのまま保持する場合はゼロ、このビットを反転する場合は1の値を持つ値をXORします。

お役に立てれば!

74
templatetypedef

いつでも_std::bitset_を使用でき、ビットの変更が簡単になります。

または、ビット操作を使用することもできます(4番目のビットが1でカウントされることを意味します。0からカウントすることを意味する場合は、1を減算しないでください)。演算全体が符号なしの数値で発生することを保証するためだけに_1U_を使用していることに注意してください。

設定するには:x |= (1U << (4 - 1));

クリアするには:x &= ~(1U << (4 - 1));

切り替えるには:x ^= (1U << (4 - 1));

14
Mark B

4番目のビットを設定するには、OR00001000(バイナリ)。

4番目のビットをクリアするには、AND with 11110111(バイナリ)。

4番目のビットを切り替えるには、XOR00001000(バイナリ)。

例:

00110010 OR 00001000 = 00111010

00110010および11110111 = 00110010

00110010 XOR 00001000 = 00111010

7
Patrick87

あなたが持っているので、またはあなたが持っている値は何でも、シンプル

int x = 50;

4番目のビット(右から)をプログラムで設定するには、

int y = x | 0x00000008;

なぜなら、0x数字の前にプレフィックスが付いているのは、16進形式であることを意味します。そう、 0x0 = 0000バイナリ、および0x8=1000バイナリ形式。それが答えを説明しています。

2

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;
}
1
Vincet

バイナリANDおよびORを使用して、4番目のビットを切り替えることができます。

Xに4番目のビットを設定するには、_x |= 1<<3;_を使用します。_1<<3_は、0b0001を3ビット左シフトして0b1000を生成します。

Xの4番目のビットをクリアするには、x &= ~(1<<3);、0b00110010(x)と(実質的に)0b11110111の間のバイナリANDを使用し、位置4にないxのすべてのビットをマスクして、クリアします。

0
Dustin Howett