bitA Tech Blog
🔰

ビットフラグとは何かをフロントエンジニア目線で整理してみた

に公開

🎄この記事は bitA Tech Blog Advent Calendar の12日目の記事です。

はじめに

案件で、フラグのステータスによって表示内容を変える実装が必要になりました。ステータスは9種類あり、数値で管理すべきか、文字列で管理すべきかで迷っていたところ、バックエンドエンジニアの夫に相談してみたところ——

夫「ビットフラグがいいと思う」

「ビット…フラグ…?」という状態だったのでビットフラグについて調べてみました。


ビットフラグとは?

ビットフラグは、1つの整数値の中に、複数の ON/OFF 状態をまとめて持たせるための仕組みです。

コンピュータの世界ではすべての情報が最終的に「0」と「1」で表現されます。このビット列の中に、各状態を1ビットずつ割り当てて管理するのがビットフラグです。

┌─┬─┬─┬─┬─┬─┬─┬─┐
│0│1│0│0│1│1│0│0│
└─┴─┴─┴─┴─┴─┴─┴─┘
 ↑ ↑ ↑ ↑ ↑ ↑ ↑ ↑
 各ビット(ON/OFF)

複数のbooleanを並べる代わりに、1つの数値で複数の状態を管理できる点が特徴です。

例えば

RPGの状態異常をフラグで管理する例を考えてみます。

ビット番号 10 進数 ステータス
0 1 毒 ☠️
1 2 眠り 😴
2 4 沈黙 🤐
3 8 混乱 😵‍💫
4 16 暗闇 😎

これをビット列で表すと次のようになります。

暗 混 黙 眠 毒
┌─┬─┬─┬─┬─┐
│0│0│0│0│0│ ← 0 が OFF、1 が ON
└─┴─┴─┴─┴─┘
 4 3 2 1 0   ← ビット番号

例えば、「毒 + 沈黙 + 混乱」が付与されている状態は以下のように表現できます。

暗 混 黙 眠 毒
0  1  1  0  1  ← ON のビット

JavaScriptで確認します。

let state = 0; // 最初は全部 OFF

// 毒を付与
state = state | 1; // ビット論理和演算子(どちらか一方でも1なら1を返す)

// 沈黙を付与
state = state | 4;

// 混乱を付与
state = state | 8;

console.log(state); // → 13 (1 + 4 + 8)
console.log(state.toString(2)); // → 1101(2進数表記)

MDN-ビット論理和演算子|

このように、数値13だけで3つの状態を同時に表現できます。


JavaScriptでの基本的な使い方

ビットフラグでは、主に次の3操作を組み合わせて状態を管理します。

1. フラグを立てる(ONにする)

state |= FLAG;

例えば毒を付与するなら 00000 |= 0000100001となり、対応するビットが1になります。

2. フラグを下げる(OFFにする)

state &= ~FLAG; 

&(ビット論理積)と ~(ビット否定)を組み合わせることで、特定のビットのみを0にできます。
例:毒を解除する場合 00001 &= ~0000100000

MDN-ビット論理積演算子&
MDN-ビット否定演算子~

3. フラグが立っているか確認する

if (state & FLAG) {
  // フラグがON
}

状態が立っていれば0以外の値になり、条件がtrueになります。

const POISON = 1;
const SLEEP = 2;
const SILENCE = 4;

let state = 0;

// 毒と沈黙を付与
state |= POISON;
state |= SILENCE;

// 毒が付与されている?
console.log(state & POISON); // 1 → true

// 沈黙を解除
state &= ~SILENCE;

console.log(state); // 1(毒だけ)

なぜビットフラグが便利なのか

✔ カラムを増やさずに済む

状態ごとにbooleanフラグを追加していくと、テーブル定義やモデルの管理が複雑になります。ビットフラグなら、1つのカラムで複数の状態を表現できるため、スキーマをシンプルに保てます。

✔ 複数の状態を自然に組み合わせられる

複数の条件を同時に持つ状態でも、1つの整数値で表現できます。
複雑なAND条件の組み合わせもビット演算で直感的に扱えます。

✔ 判定が高速で、実装もシンプル

ビット演算(ANDOR)は非常に高速で、処理の意図も明確になります。
「特定の状態がONかどうか?」の判定も一行で書けます。

ただし向かない場合も

ただし、「常にビットフラグが正解」というわけではありません。

  • 状態が少ない
  • 将来増える予定がない
  • 可読性を最優先したい

といった場合は、booleanを素直に並べた方が理解しやすいこともあります。


まとめ

2進数やビット演算に慣れていなかったこともあり、図を描いてようやく理解できましたが、とても良い学びになりました。

結果として案件ではビットフラグを採用しませんでしたが、ON/OFFの状態を多く扱うケースでは、よりシンプルにまとめられる便利な仕組みだと感じました。

👋 最後まで読んでいただきありがとうございました!

bitA Tech Blog
bitA Tech Blog

Discussion