| (bitwise OR) の解説と実装リファレンス
【概要】
ビット演算子 | は、2つの整数の各ビットを比較し、いずれかのビットが「1」であれば結果のビットを「1」とする演算(ビット単位の論理和)を行う。この演算は、数値の論理的な真偽を判定するのではなく、メモリ上のビット列に対して直接作用する。
【仕様】
- 対象データ型:
uint8_t,uint16_t,uint32_t,int,long等の整数型。 - 演算規則: 各ビット位置について、以下の真理値表に従う。
0 | 0 = 00 | 1 = 11 | 0 = 11 | 1 = 1- 戻り値: 演算に用いられた型と同一の型で、演算結果を保持する。
- 演算特性: 非破壊的なビットセット(特定のビットのみを1にする操作)の基本演算として機能する。
【技術的特徴】
- ハードウェアレベルの挙動: ほとんどのマイクロコントローラ(AVR, ESP32, STM32等)において、ビット演算は専用のCPU命令(例:
OR)として実装されており、極めて低レイテンシで実行される。 - 論理OR (
||) との比較: ||(論理和)は、左辺が「真(非ゼロ)」であれば右辺を評価せずに結果を返す「短絡評価(ショートサーキット)」を行う。|(ビット演算)は、すべてのビットに対して演算を行い、短絡評価は行わない。- ビットマスクとの親和性: 特定のビットを「ON」にするために、シフト演算(
<<)と組み合わせることが標準的な手法である。
【注意点】
- Integer Promotion(整数昇格): 8ビットマイコン(Arduino Uno等のAVR)において、
uint8_t型の演算を行う際、内部的にint型へ昇格されることがある。この際、上位ビットの挙動に注意が必要であり、安全のため符号なし型(unsigned)の使用が推奨される。 - Read-Modify-Write (RMW) の原子性:
register |= (1 << bit)という記述は、実際には「読み込み」「演算」「書き込み」の3工程を順次実行する。マルチタスク環境や割り込み処理が介入する環境では、この操作の間に他の処理が介入し、データ競合が発生する可能性がある。必要に応じてクリティカルセクション(割り込み禁止など)の保護が必要となる。 - 符号付き整数のオーバーフロー: 符号付き整数(
int)に対してビット演算を行う場合、最上位ビット(MSB)が符号ビットとして扱われるため、意図しない負数への変換や符号の反転を引き起こす可能性がある。
【サンプルコード】
#include <Arduino.h>
// 状態フラグの定義(ビットマスク)
#define FLAG_READY (1 << 0) // 0b00000001
#define FLAG_ERROR (1 << 1) // 0b00000010
#define FLAG_ACTIVE (1 << 2) // 0b00000100
uint8_t system_status = 0;
void setup() {
Serial.begin(9600);
}
void loop() {
// 1. 特定のフラグをビット演算でセット(現在の状態を維持したまま反映)
system_status |= FLAG_READY;
// 2. 複数のフラグを同時にセット
system_status |= (FLAG_ERROR | FLAG_ACTIVE);
Serial.print("Status: ");
Serial.println(system_status, BIN); // 2進数で表示
delay(2000);
}
【活用例】
- レジスタ制御: GPIOポートの特定のピンのみをHIGHにする操作(例:
PORTB |= (1 << 5);)。 - ステータス管理: 複数の状態(エラー、通信中、待機中など)を1つの変数内にビットとして保持し、メモリを節約しながら状態を合成・管理する。
- 通信プロトコル: 通信パケットのフラグフィールドの構築。複数の独立したフラグを一つのバイトに統合する際に多用される。


コメント