~ (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;


コメント