| (bitwise OR) の解説と実装リファレンス

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

| (bitwise OR) の解説と実装リファレンス

【概要】

ビット演算子 | は、2つの整数の各ビットを比較し、いずれかのビットが「1」であれば結果のビットを「1」とする演算(ビット単位の論理和)を行う。この演算は、数値の論理的な真偽を判定するのではなく、メモリ上のビット列に対して直接作用する。

【仕様】

  • 対象データ型: uint8_t, uint16_t, uint32_t, int, long 等の整数型。
  • 演算規則: 各ビット位置について、以下の真理値表に従う。
  • 0 | 0 = 0
  • 0 | 1 = 1
  • 1 | 0 = 1
  • 1 | 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つの変数内にビットとして保持し、メモリを節約しながら状態を合成・管理する。
  • 通信プロトコル: 通信パケットのフラグフィールドの構築。複数の独立したフラグを一つのバイトに統合する際に多用される。

コメント

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