ビット演算子

広告

整数の値に対してビット単位で処理を行うために用意されているのがビット演算子です。次の演算子が用意されています。

演算子使用例意味
&a & 0xFF00FF00a と 0xFF00FF00のビットAND
|a | 0xFF00FF00a と OxFF00FF00のビットOR
^a ^ 0xFF00FF00a と OxFF00FF00のビットXOR
~~aa のビット反転(ビットNOT)
<<a << 3a を 左へ3ビットシフト
>>a >> 3a を 右へ3ビットシフト(符号有り)
>>>a >>> 3a を 右へ3ビットシフト(符号無し)

前述している通り、JavaScriptでは内部的に数値は全て浮動小数点数として処理されます。ただ、ビット演算子は整数に対して使用されるため対象の値は32ビットの整数に変換されてから処理されます。その為、整数ではない数値や、32ビットで表すことが可能な整数を越える大きな整数に対してビット演算子を使用する場合は予期しない結果になる場合があります。

ビット演算では数値を2進数の形式で表示し、各ビットに対して演算を行います。例えば0x3F30A5A5という数値を2進数で表すと次のようになります。

0x3F30A5A5

0011 1111 0011 0000 1010 0101 1010 0101
---- ---- ---- ---- ---- ---- ---- ----
 3    F    3    0    A    5    A    5

0x3F30A5A5という16進数で表記された整数を2進数で表すと00111111001100001010010110100101となります。ビット演算子を使用すると2進数で表された各ビットに対して操作を行う事ができます。

では順に確認していきます。(「<<」「>>」「>>>」の3つの演算子については次のページで説明します。)

ビットAND

ビットANDは演算子の左辺と右辺の同じ位置にあるビットを比較して、両方のビットが共に「1」の場合だけ「1」にします。次の例を見てください。

var num;
num = 0x55 & 0x0F;

変数「num」には0x55と0x0FのビットANDした結果が代入されます。この時、次のような処理が行われます。

00000000 00000000 00000000 01010101  = 0x55
00000000 00000000 00000000 00001111  = 0x0F
-------------------------------------------
00000000 00000000 00000000 00000101  = 0x05

0x55と0x0Fをそれぞれ2進数で表します。そして各ビットを比較し両方のビットが「1」の場合だけ「1」となり、それ以外の場合は全て「0」となります。結果として00000000000000000000000000000101(0x05)という値が変数「num」には代入されることになります。

ビットOR

ビットORは演算子の左辺と右辺の同じ位置にあるビットを比較して、どちらか一つでもビット「1」の場合に「1」にします。次の例を見てください。

var num;
num = 0x55 | 0x0F;

変数「num」には0x55と0x0FのビットORした結果が代入されます。この時、次のような処理が行われます。

00000000 00000000 00000000 01010101  = 0x55
00000000 00000000 00000000 00001111  = 0x0F
-------------------------------------------
00000000 00000000 00000000 01011111  = 0x5F

0x55と0x0Fをそれぞれ2進数で表します。そして各ビットを比較しどちらかのビットが「1」の場合は「1」に、両方のビットが「0」の場合は「0」にします。結果として00000000000000000000000001011111(0x5F)という値が変数「num」には代入されることになります。

ビットXOR

ビットXORは演算子の左辺と右辺の同じ位置にあるビットを比較して、どちらかのビットが一つだけ「1」の場合に「1」にします。次の例を見てください。

var num;
num = 0x55 ^ 0x0F;

変数「num」には0x55と0x0FのビットXORした結果が代入されます。この時、次のような処理が行われます。

00000000 00000000 00000000 01010101  = 0x55
00000000 00000000 00000000 00001111  = 0x0F
-------------------------------------------
00000000 00000000 00000000 01011010  = 0x5A

0x55と0x0Fをそれぞれ2進数で表します。そして各ビットを比較しどちらかのビット一つだけが「1」の場合には「1」に、両方のビットが「1」であるか両方のビットが「0」の場合は「0」にします。結果として01011010(0x5A)という値が変数「num」には代入されることになります。

ビットNOT

ビットNOTは演算子の右辺の値の各ビットを反転(0なら1に、1なら0にする)させます。次の例を見てください。

var num;
num = ~0x55;

変数「num」には0x55をビットNOTした結果が代入されます。この時、次のような処理が行われます。

00000000 00000000 00000000 01010101  = 0x55
-------------------------------------------
11111111 11111111 11111111 10101010  = 0xAA

0x55を2進数で表します。そして各ビットを「0」なら「1」に、「1」なら「0」にします。結果として11111111111111111111111110101010(0xFFFFFFAA、10進数だと-86)という値が変数「num」には代入されることになります。

サンプルコード

では簡単なサンプルで試してみます。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<title>JavaScript テスト</title>
</head>
<body>

<script type="text/javascript" src="./js/script8_1.js">
</script>

</body>
</html>
var num;

num = 0x55 & 0x0F;
document.write("<p>0x55 & 0x0F = " + num + "</p>");

num = 0x55 | 0x0F;
document.write("<p>0x55 | 0x0F = " + num + "</p>");

num = 0x55 ^ 0x0F;
document.write("<p>0x55 ^ 0x0F = " + num + "</p>");

num = ~0x55;
document.write("<p>~0x55 = " + num + "</p>");

上記を実際にブラウザ見てみると次のように表示されます。

p8-1

( Written by Tatsuo Ikura )