ビット演算は、昔はメモリ領域の節約のために用いられる手法でしたが、最近ではメモリも潤沢にあるので、使う機会も減りました。
ですが、使いどころによっては様々な状態を表す演算として有用となりますので、いつでも使えるようにしておくことが望ましい機能です。
本記事では、JavaScriptにおけるビット演算について解説します。
記事内に記載しているプログラムは、Node.js14.14.0を使って動作確認をしています。
JavaScriptのビット演算
JavaScriptのビット演算について、以下の内容を解説します。
- JavaScriptでのビット演算の扱い方
- AND演算
- OR演算
- XOR演算
- NOT演算
- 左シフト演算
- 符号あり右シフト演算
- 符号なし右シフト演算
JavaScriptでのビット演算の扱い方
ビット演算はその名の通り、1ビット単位で演算を行うので、プログラムも2進数で表現していきます。
JavaScriptで2進数で表現するには、先頭に 0b をつけます。
a = 0b0110; console.log(a); // -> 10
2進数のまま表示するには、toString(2)をつけます。
console.log(a.toString(2)); // -> 1010
上記の方法では、値によって桁数が一定でなく、分かりづらいことがあるので、例えば8桁に揃える場合は以下のようにします。
console.log(a.toString(2).padStart(8, '0')); // -> 00001010
AND演算
AND演算を行うには、演算子&を使います。
AND演算は演算するビット同士が1であれば結果は1、それ以外の組み合わせは0となる計算を行います。
a = 0b1010; b = 0b0110; result = a & b; console.log(result); // -> 2 console.log(result.toString(2).padStart(8, '0')); // -> 00000010
上記のプログラムは、「0b1010」と「0b0110」のAND演算になるので、結果は「0b0010」となって2となります。
OR演算
OR演算を行うには、演算子|を使います。
OR演算は演算するどちらかのビット1であれば結果は1、両方のビットが0であれば結果は0となる計算を行います。
a = 0b1010; b = 0b0110; result = a | b; console.log(result); // -> 14 console.log(result.toString(2).padStart(8, '0')); // -> 00001110
上記のプログラムは、「0b1010」と「0b0110」のOR演算になるので、結果は「0b1110」となって14となります。
XOR演算
XOR演算を行うには、演算子^を使います。
XOR演算は演算するビットが0と1で異なる場合は結果は1、ビットが同じ0同士または1同士であれば結果は0となる計算を行います。
a = 0b1010; b = 0b0110; result = a ^ b; console.log(result); // -> 12 console.log(result.toString(2).padStart(8, '0')); // -> 00001100
上記のプログラムは、「0b1010」と「0b0110」のXOR演算になるので、結果は「0b1100」となって12となります。
NOT演算
NOT演算を行うには、演算子~を使います。
NOT演算は1つ値の持つ各ビットを反転させる計算を行います。
a = 0b1010; result = ~a; console.log(result); // -> -7 console.log(result.toString(2)); // -> -111
上記のプログラムは、「0b1010」の各ビットを反転させて1を加えた補数表現となります。
左シフト演算
左シフト演算は、演算子<<を使って、ビットをそのまま指定した数だけ左に移動させます。
左端はそのまま桁あふれとなり、右端から0が入ってきます。
a = 0b1010; result = a << 2; console.log(result); // -> 40 console.log(result.toString(2).padStart(8, '0')); // -> 00101000
上記のプログラムは、「0b1010」を2桁左に移動して、「0b101000」となって40となります。
左シフトするごとに2倍になっていくことになります。
符号あり右シフト演算
符号あり右シフト演算は、演算子>>を使って、ビットをそのまま指定した数だけ右に移動させます。
右端は切り捨てられ、左端は正の数であれば0、負の数であれば1が入って、符号をそのまま引継ぎます。
a = 0b1010; result = a >> 2; console.log(result); // -> 2 console.log(result.toString(2).padStart(8, '0')); // -> 00000010
上記のプログラムは、「0b1010」を2桁左に移動して、「0b0010」となって2となります。
右シフトするごとに1/2になっていくことになります。
端数は切り捨てられ、最終的に0となります。
なお、負の数に対して、>>による右シフト演算を行うと、負数のまま右シフトとした補数表現となります。
符号なし右シフト演算
符号なし右シフト演算は、演算子>>>を使って、ビットをそのまま指定した数だけ右に移動させます。
右端は切り捨てられ、左端は必ず0が入ります。
a = 0b1010; result = a >>> 2; console.log(result); // -> 2 console.log(result.toString(2).padStart(8, '0')); // -> 00000010
上記のプログラムは、「0b1010」を2桁右に移動して、「0b0010」となって2となります。
なお、負の数に対して、>>>による右シフト演算を行うと、符号部分が0となるため正の数となります。
まとめ
JavaScriptのビット演算についてまとめると、以下となります。
- JavaScriptで2進数を扱うには、値の先頭に0bを付ける。
- ビット演算は各ビットに対して演算を行う。
- シフト演算は各ビットを移動させて演算を行う。
通常あまり使う機会はないかもしれませんが、桁に意味を持たせてフラグ管理したい場合などに使ってみてはいかがでしょうか。
今回は、JavaScriptのビット演算について解説しました。
以上、参考になれば幸いです。
コメント