hottyです。
第3回の演算子編で紹介できなかったビット演算子について今回は紹介します。
ビット演算が必要な場面はけっこう限られてくると思いますが知っておくといざというときに役に立ちます。

第1回目 javascript入門/配列編
第2回目 javascript入門/正規表現編
第3回目 javascript入門/演算子編

ビット演算子とは

ビット演算子はビット単位での処理を行いたいときに使用します。ビット単位での処理のことを「ビットマスク」と呼び、ビット単位で処理をすることを「ビットをマスクする」などという呼び方をします。
ビット演算子は32ビット数で動作します。演算子に与えられた任意の数字は一度32ビットの数字に変換され、マスクした結果は javascriptの数字(10進数)に変換されます。

ビット演算子: &, |, ~, ^, <<, >>

&

「&」はANDです。ビットを0にマスクしたい時に使います。したがって用途は特定のビットをオフにしたいときです。ビットが1の時をオン、ビットが0の時をオフなどと呼びます。

例えば、「7」を2進数で表すと「111」、「4」を2進数で表すと「100」ですね。ANDは2進数の各ケタに対して共にオンである時にオンとなり どちらかがオフであればオフになります。

ということで、結果は「100」でありこれは10進数で「4」です。つまり「7 & 4」は「4」を返します。

順番が逆ならどうでしょうか。

やはり結果は同じですね。「4 & 7」も結果は「4」です。

|

「|」はORです。特定のビットをオンにしたいときに使用します。ORは2進数の各ケタに対してどちらかがオンである時にオンとなり どちらもオフである時にオフとなります。

ということで、結果は「111」でありこれは10進数で「7」です。「7 | 4 」は「7」を返します。

~

「~」はNOTです。NOTは強制的にすべてのビットを反転します。オンであるビットがオフにスイッチされ オフであるビットがオンにスイッチされます。

この結果はどうなるでしょうか。反転なので「111」が「000」になり結果は「0」かと思いますが実際は「-8」です。

脱線しますが2進数でマイナスを表現する時はどうすれば良いでしょうか?

オフセットバイナリ、1の補数表現、2の補数表現などいくつか方法はあるかと思いますが 一般的に使われることが多いのは2の補数表現のようです。

8ビットは符号なしの場合 0〜255 の256通りの数字を表現できますが 2の補数表現では -128〜127 までの 256通りとなります。MySQLの数値型カラムで「UNSIGNED」という属性をつけると格納できる数字の数が倍になります。これは符号なし表現だと「符号を表現するためのビットパターン」を考えなくて良いためです。もちろん javascirptで符号は扱えます。ということはjavascriptの2進数の扱いは「符号あり」です。

これを踏まえた上で先ほどの例を考えてみます。「7」という数字は1バイト、ということは8ビットです。つまり正確には「111」ではなく「00000111」です。これをNOTで反転させると「11111000」です。これは符号なしの表現では「248」ですが 2の補数表現では「-8」です。「~ 7」 が 「-8」になる理由がお分かり頂けたでしょうか?

ちなみに Ecmascriptのドキュメントを見ると整数にキャストされるようなので「~ “7”」でもOKです。

せっかくなので「1の補数表現」「2の補数表現」の違いなども詳しく解説していきたいですが「補数」や「基数、減基数」など数学の話になってしまうのでまた別の機会ということで…。

^

「^」はXORです。「5 ^ 10」は「15」を返します。10を2進数で表すと「00001010」です。「00001010」のうちビットがオンになっている桁に対して反転を行うというマスクです。

となり「00001111」は10進数で「15」です。簡単にいうと部分反転です。

<<

「<<」はLEFT-SHIFTです。左にシフト(動かす)という意味です。左に1つ動いて空いた位置には0が入ります。

例えば、10(00001010)を左に1つ動かすと「000010100」となります。「000010100」は10進法で「20」です。

>>

「>>」はRIGHT-SHIFTです。右にシフト(動かす)という意味です。符号ありの場合は符号の情報を失わないようにシフトします。

例えば、-10(11110110)を右に1つ動かすと「11111011」となります。符号の情報が失われないように空いた位置に1が入ります。「11111011」は10進法で「-5」です。

以上でビット演算子の紹介は終わりです。
この記事はjavascript初心者(プログラム初心者)の方をターゲットにしてますが ビット演算の説明はどうしてもわかりにくくなってしまいます。
でも雰囲気だけでもわかって頂ければうれしく思います。

あわせて読みたい記事