~ (bitwise NOT) の解説と実装リファレンス

記事内には広告が含まれています。

~ (bitwise NOT) の解説と実装リファレンス

【概要】

ビット演算子 ~(ビット反転)は、与えられた数値のすべてのビットを反転させる単項演算子です。具体的には、各ビットの 0 を 1 に、1 を 0 に変換します。この操作は、特定のビットを反転させたり、マスク処理の逆転を行ったりする際に、低レイヤーのハードウェア制御やビット操作において頻繁に使用されます。

【仕様】

  • 演算子: ~ (Unary Bitwise NOT)
  • 引数: 整数型(uint8_t, int16_t, uint32_t, int 等)
  • 戻り値: 入力されたデータ型と同じビット幅の反転値
  • 動作原理: 各ビット b に対して、ノット・ビー を適用する。
  • 数学的関係: 2の補数表現において、~x は -(x + 1) と等価となる。

【技術的特徴】

1. ハードウェアレベルの挙動

ほとんどのマイクロコントローラ(AVR, ESP32, STM32等)において、~ は単一のCPU命令(例: COM や XOR を用いた演算)として実装されており、計算コストは極めて低いです。

2. 論理否定(!)との違い

よく混同される論理否定演算子 ! とは動作が根本的に異なります。
– ! (Logical NOT): 値が「0」であれば「1」を、「0以外」であれば「0」を返します。結果は常に 0 または 1 です。
– ~ (Bitwise NOT): 数値の全ビットを反転させます。結果は元のビット幅に応じた範囲の数値となります。

3. 比較表

| 演算子 | 入力 (8bit) | 動作 | 出力 (8bit) | 備考 |
| ! | 00000001 | 論理判定 | 0 | 真偽判定用 |
| ~ | 00000001 | ビット反転 | 11111110 | ビット操作用 |

【注意点】

1. 整数昇格 (Integer Promotion)

C/C++の仕様上、uint8_t などの小さな型に対して ~ を適用する際、演算前に int 型に昇格されることがあります。これにより、意図しない上位ビットまで反転される現象が発生します。正確なビット操作を行う際は、適切なキャストを行うか、型を意識したマスク処理が必要です。

2. 符号の扱い

符号付き整数(int, int16_t 等)に対して ~ を適用すると、最上位ビット(符号ビット)も反転します。これにより、正の数が負の数に変化する場合があるため、ビットフラグの管理には unsigned 型(uint8_t 等)を使用するのが標準的なプラクティスです。

【サンプルコード】

#include <Arduino.h>

void setup() {
  Serial.begin(9600);
}

void loop() {
  // 1. 基本的なビット反転
  uint8_t original = 0b00001111; // 0x0F
  uint8_t inverted = ~original;   // 0b11110000 (0xF0)

  Serial.print("Original: ");
  Serial.println(original, BIN);
  Serial.print("Inverted: ");
  Serial.println(inverted, BIN);

  // 2. 論理否定との比較
  uint8_t val = 0x01;
  Serial.print("Logical NOT (!): ");
  Serial.println(!val); // 結果: 0

  Serial.print("Bitwise NOT (~): ");
  Serial.println(~val, BIN);

  delay(5000);
}

【活用例】

1. レジスタのビットマスク反転

特定のビットのみを「クリア(0にする)」したい場合、AND 演算と ~ を組み合わせます。

// 例: 0x03 (00000011) のビットをクリアしたい場合
uint8_t register_val = 0xFF; 
register_val &= ~0x03; // 0xFF & 11111100 -> 11111100

2. 特定ビットの反転 (Toggle)

XOR と組み合わせることで、特定のビットを反転させることができます。

// 0x01 のビットを反転させる
egister_val ^= 0x01; 

3. 状態フラグの完全反転\n特定のシステム状態を、すべてのビットを反転させることで一括で操作する際に利用されます(例:全点灯から全消灯への一括切り替えなど)。

コメント

タイトルとURLをコピーしました