JavaScriptで数値のビット抽出… n~mビット目を抽出する方法とコード例

こういう風なことを実現したいです。

  • 数値(2進数表記)の 10110111  がある
  • そのn~mビット目を抽出したい
  • 例えば3~5ビット目なら 110  みたいに

※ ただし n , m は1から始まる番号

もちろんビット演算を使えば可能です。

ただ少し混乱することが多いので、
自分用にビット抽出方法とコード例をまとめました。

まずビット演算子(左シフト/右シフト)について

まず大前提として次の2つ演算子を利用します

  • <<  : ビットの左シフト
  • >>  : ビットの右シフト

簡単にまとめると次の通りです。

ビットの左シフト(<<) の動作と使い方

これはビットを左にnビット詰める演算子

▼ ある数値を4ビット左シフトする例

左にシフトした分は 0 で埋められます。

ちなみに2進数を扱うときは num.toString(2)  とすると2進数表記で数値(というか文字列)を確認できます。このテクニックはビット演算の動作を確認するのに便利です。

そして上コードの左シフトですが……
細かく丁寧に分解すると次の動作をしてます。

▼ 左シフトの動作イメージ

とにかく左に詰めてるイメージ

ビットの右シフト(>>) の動作と使い方

これはもう単純に左シフトの逆です。

▼ ある数値を4ビット右シフトする例

右にシフトした分は 0 で埋められます。

これも一応動きを確認してみましょう

▼ 右シフトの動作イメージ

演算子の向き( >> )で覚えればOK

n~mビット目までを抽出する方法とコード例

ようやく本題に入ります。

ある2進数の数値・データに対して、

n~mビット目までを数値として抽出

こういう操作をするための方法についてです。

▼ 単純に次のコードでビット抽出可能

▼ 汎用性を考えて関数化

この関数は前半と後半に分けられます。

  • 前半 :  ((1<<(m-n+1))-1)
    この部分ではマスク用のビット列を作成。例えば n = 2, m = 6 なら抽出ビット数は 5 になるため、 ((1<<(6-2+1))-1) = ((1<<5)-1) = (b100000-b1) = b11111  のビット列ができあがる。
  • 後半 :  (num>>(n-1))
    この部分ではnビットだけ右シフトしている。これと前述のマスク用ビット列のビット積を取ることでn~mビットだけの値が取得できる。

そしてもう1つ重要なことがあります。

それは右端から左にn~mビットを抽出すること

左端から右ではないので注意してください

このextraBits()によるビット抽出の例

いくつか適当なビット列で試してみます。

▼ n~mビット目までのビット抽出のコード例

※ 分かりやすさ優先のためにMonospacefフォント使用

任意範囲のビット抽出が可能。こういう感じです。

ビット抽出はマニアックだけど使われる場面が多い

マニアックというと少し語弊があるけど…

  • バイナリフォーマットの解析をしたい時
  • 数値をバイナリとして扱いたい時
  • データを無駄なく神経質に扱いたい時

こういう場面で役立つかもしれません。

以上、JSでのn~mビット抽出でした。ではまた