ビット演算子
&, |, ^, ~:ビット演算子
ビット演算子は、数値のビットレベルでの計算を実行します。
これらは、幅広い一般的なプログラミング問題を解決するのに役立ちます。
以下は、すべての演算子の説明と構文です。
ビット単位のAND演算子 (&)
C ++のビット単位のAND演算子は、他の2つの整数式の間に使用される1つのアンパサンド(&)です。 ビット単位のANDは、この規則に従って、演算対象の両側の式の各ビット位置で独立して動作します。両方の入力ビットが1の場合、結果の出力は1、それ以外の場合は0の出力です。これを表現する別の方法は次のとおりです。
code:AND
0 0 1 1 オペランド1
0 1 0 1 オペランド2
----------
0 0 0 1 (オペランド1 & オペランド2) = 演算結果
Maple(Arduino STM32)では、int型は32ビットの値なので、2つのint式の間に'&'を使用すると32のAND演算が同時に発生します。 コードでは次のようになります。
code:AND
int a = 92; // in binary: 00000000000000000000000001011100
int b = 101; // in binary: 00000000000000000000000001100101
int c = a & b; // result: 00000000000000000000000001000100,
// (or 68 in decimal).
aとbの32ビットはそれぞれビット単位のANDを使用して処理され、結果の32ビットはすべてcに格納され、結果として1000100が2進数で、10進数で68になります。
ビット単位のOR演算子(|)
C ++のビット単位のOR演算子は、垂直バー記号|です。 &演算子と同様、|演算子は演算対象の両側の整数式の各ビットで独立して動作しますが、その動作は異なります。 入力ビットのいずれかまたは両方が1であれば2ビットのビット単位の論理和が1で、それ以外の場合は0です。たとえば、次のようになります。
code:OR
0 0 1 1 operand1
0 1 0 1 operand2
----------
0 1 1 1 (operand1 | operand2) = result
次に、C ++コードのスニペットで使用されるビット単位のORの例を示します(32ビットを使用するintの代わりに8ビットのメモリを使用するcharを使用)。
code:OR
char a = 92; // in binary: 01011100
char b = 101; // in binary: 01100101
char c = a | b; // result: 01111101, or 125 in decimal.
ビット単位のXOR演算子(^)
C ++には、ビット単位の排他的論理和(bitwise EXCLUSIVE OR)と呼ばれるやや珍しい演算子があります。
これはビット単位のXORとも呼ばれます。 (英語では、これは通常 "zor"または "ex-or"と発音されます)。
ビット単位のXOR演算子は、キャレット記号^を使用して記述されます。
この演算子は、入力ビットの両方が1のとき、0と評価される点を除き、ビット単位のOR演算子|と非常によく似ています。
code:XOR
0 0 1 1 operand1
0 1 0 1 operand2
----------
0 1 1 0 (operand1 ^ operand2) = result
ビット単位のXORを調べるもう1つの方法は、入力ビットが異なる場合は結果の各ビットが1、同じ場合は0になります。
ここに簡単な例があります:
code:XOR
int x = 12; // binary (ignoring extra bits): 1100
int y = 10; // binary: 1010
int z = x ^ y; // binary: 0110, or decimal 6
^演算子は、整数式の一部のビットをトグル(すなわち、0から1または1から0に変更)するために使用されることが多い。 ビット単位のOR演算では、マスクビットに1がある場合、そのビットは反転されます。 0があれば、そのビットは反転せず同じままである。 以下は、内蔵のLEDピンを切り替えるプログラムです(toggleLED()でこれを実現することもできます)。
code:ToggleLED.ino
// Toggle built-in LED pin
int toggle = 0;
// demo for Exclusive OR
void setup(){
pinMode(BOARD_LED_PIN, OUTPUT);
}
void loop(){
toggle = toggle ^ 1;
digitalWrite(BOARD_LED_PIN, toggle);
delay(100);
}
ビット単位のNOT演算子(~)
C ++のビット単位のNOT演算子はチルダ文字~です。 &と|と異なり、ビット単位のNOT演算子は、その右側の単一のオペランドに適用されます。 ビット単位NOT演算子は各ビットをその反対に変更します。0は1になり、1は0になります。例:
code:NOT
0 1 operand1
----
1 0 ~operand1 = result
もう一つの例:
code:NOT
char a = 103; // binary: 01100111
char b = ~a; // binary: 10011000 = -104
この操作の結果として-104のような負の数を見ることに驚くかもしれません。 これは、int変数の最上位ビットがいわゆる "符号ビット"であるためです。 最上位ビットが1の場合、数値は負と解釈されます。 正と負の数のこの符号化は、2の補数と呼ばれる。 詳細については、2の補数に関するWikipediaの記事を参照してください。 さて、任意の整数x、~xについて(2の補数演算の下で)-x-1と同じであることに注意することは興味深いことです。
時には、符号付き整数式の符号ビットは、いくつかの望ましくない驚きを引き起こす可能性があります。
用途
ビット単位演算の最も一般的な用途の1つは、ビットマスクと呼ばれることが多い整数値から特定のビット(1つまたは複数)を選択または操作することです。 詳細と例についてはリンク先のWikipediaの記事を参照してください。 完璧で素晴らしいビット操作技術(bit-twiddling techniques)が知りたいのであれば、Hacker’s Delightのコピーを手に入れるのも良いでしょう。 関連項目
このドキュメントはleafLabs, LLC.が執筆し、たま吉が翻訳・一部加筆修正したものです。