web-dev-qa-db-ja.com

Cでバイトの特定のビットを反転する方法は?

マスクを使用して、バイト内の特定のビットを操作しようとしています。例えば:

特定の位置で2ビットを反転するプログラムをCで記述したいと思います。位置0のビットと3番目の位置のビット。したがって、1110001101110011になります。

これらのビットをどのように交換できますか?

21
Niels Robben

ビットの反転は、マスクを使用したXOR処理によって行われます。反転する位置にビットを設定し、次のようにXORを実行します。

int mask = 0x90; // 10010000
int num  = 0xE3; // 11100011
num ^= mask;     // 01110011

ここにいくつかのメモがあります:

  1. ビットは通常、最下位位置からカウントされるため、この例では、位置0および4ではなく、位置4および7のビットを反転します。
  2. 単一の位置のビットマスクを作成するには、式1 << nを使用します。ここで、nは最下位ビットから数えた位置番号です。
  3. 1つのマスクで複数のビットを組み合わせるには、|演算子を使用します。たとえば、(1 << 4) | (1 << 7)は、ビット4と7を反転するためのマスクを作成します。
27
dasblinkenlight

バイトがxで、i番目とj番目の位置でビットを切り替えたい場合:

x = x ^ ((1<<i) | (1<<j));

したがって、あなたの場合、それは単に(1 << 4)になります。 (1 << 7)。 :)

3
Eutherpy

まずは頑張って!

備考-さまざまなバイト/ワードサイズ(8ビット、16ビットなど)があり、互換性をよりよく保つため、左からではなく右からビットをカウントする方が便利です。したがって、あなたのケースでは、ビット#7と#4(ゼロカウント)を参照しています。

「フリップ」(0 <-> 1ビットを変更)を意味しますか、それとも、それらを一方と他方の間で「切り替え」ますか?

最初のオプションの場合、上記の答え(XORと "int mask = 0x90; // 10010000")は非常に適切です。 2番目のものについては、少しトリッキーです(ただしそれほどではありません)。

1
AssafR

ビットを反転するには、排他的なORビットごとの演算子を使用できます。これは、2つのオペランド(通常、操作する値と、どのビットを反転するかを定義するマスク)をとります。)eXclusive = OR(XOR)演算子は、2つのうちの1つが1に設定されている場合にのみビットを反転しますが、両方には設定されません。以下の(簡単な)例を参照してください:

#include <stdio.h>

int main(int argc, char** argv)
{
   int num = 7;   //00000111
   int mask = 3;  //00000011

   int result = num ^ mask; //00000100
   printf("result = %d\n", result); //should be 4

   return 0;
}
1