ビット演算子の復習。

通常数値リテラルとして扱う場合は、10進数や8進数、16進数などを使用する機会が多いが、ビット演算子は32ビットの集合として扱うため2進数の計算となる。

2進数の計算は1ビットで示すことができる情報処理の基礎となるが、あまりコーポレートサイトなど静的なコーディングで使用する機会はない。

今回はビット演算子の復習のために、無理やりビットマスクを使ってみる。

ビットマスクとは

ビットマスクとは、通常真偽値として使用されるbool型は2種類としか値がないが、これを「真 = 1」「偽 = 0」として1ビットで表現することで、2進数を用い一つの変数で複数の真偽値を表現することである。

ビットマスクを用いることで、視認性が下がるがオブジェクトアクセスなどのメモリリソースを抑えられ、高速処理することができため、ゲームプログラミングなどでよく用いられる。

数値リテラルについて

各進数の使い方についてまとめてみた。

ヘキサリテラル

// 16進数表記(0x)
console.log(0x00000112); // 274

オクタルリテラル

// 8進数表記(0o)
console.log(0o00000112); // 74

バイナリリテラル

// 2進数表記(0b)
console.log(0b00000110); // 6

ビット演算子の種類

  • a & b:ビットごとのAND
    オペランドの対応するビットがともに 1 である各ビットについて 1 を返す。
  • a | b:ビットごとのOR
    オペランドの対応するビットがどちらかまたはともに 1 である各ビットについて 1 を返す。
  • a ^ b:ビットごとのXOR
    オペランドの対応するビットがどちらか一方のみ 1 である各ビットについて 1 を返す。
  • ~ a:NOT:ビットごとのNOT
    オペランドの各ビットを反転する。
  •  a << b:左シフト
     2 進表現の a を b (< 32) ビット分だけ左にシフトし、右から 0 を詰める。
  • a >> b:符号を維持した右シフト
    2 進表現の a を b (< 32) ビット分だけ右にシフトし、溢れたビットは破棄する。
  • a >>> b:0 埋め右シフト
    2 進表現の a を b (< 32) ビット分だけ右にシフトします。溢れたビットは破棄し、左から 0 を詰める。
// AND
console.log(0b0101 & 0b1010); // 0 = 0b0000

// OR
console.log(0b0101 | 0b1010); // 15 = 0b1111

// XOR
console.log(0b0101 ^ 0b1011); // 14 = 0b1110

// NOT
console.log(~ 0b1110); // -15

各自 Developer Tool で試してみて欲しい。

ビットマスクの使用例

最後にビットマスクの使い方を見てみる。

let flag = 0b0000;
// 各フラグ
const A = 0b0001; // 1桁目をフラグに設定
const B = 0b0010; // 2桁目をフラグに設定
const C = 0b0100; // 3桁目をフラグに設定

// フラグの追加
flag = flag | A; // 0b0001
// 下記のようにも記述できる
flag |= B; // 0b0011

// フラグの削除
flag = (flag | B) ^ B; // 0b0001

// フラグの判定
console.log( (flag & A) !== 0 ); // true:Aのフラグを立っていれば、0以外の数値を返す
カテゴリー: All