シフト演算子

広告

ビット演算子の中でも下記の3つはシフト演算子と呼ばれることもあります。

演算子使用例意味
<<a << 3a を 左へ3ビットシフト
>>a >> 3a を 右へ3ビットシフト(符号有り)
>>>a >>> 3a を 右へ3ビットシフト(符号無し)

これらの3つの演算子は演算子の左側に記述された値を、右側に記述した値の数だけ右または左へシフトします。右側に記述できる値は1から31までの範囲の整数で指定します。

10進数で右または左へ数値をシフトした場合、それは数値を1/10にしたり10倍することを意味します。例えば1230を左へシフトして12300とすれば10倍したことになりますし、右へシフトして123とすれば1/10になったこととなります。同じように2進数でシフトした場合は1/2にしたり2倍したりすることを意味します。

では順に確認していきます。

左シフト

「<<」演算子は対象の値を指定した数だけ左へシフトします。次の例を見てください。

var num;
num = 0x15 << 2;

変数「num」には0x15を左へ2つシフトした値が代入されます。この場合は次のような処理が行われます。

00000000 00000000 00000000 00010101  = 0x15
-------------------------------------------
00000000 00000000 00000000 00101010  = 0x2A  (1つシフト)
00000000 00000000 00000000 01010100  = 0x54  (2つシフト)

0x15を左へ2つシフトすると00000000000000000000000001010100(0x54)となります。左へシフトする場合、左側からはみ出たビットは捨てられ、シフトしたことによて空いた右側には0が詰められます。

右シフト(符号有り)

「>>」演算子は対象の値を指定した数だけ右へシフトします。次の例を見てください。

var num;
num = 0x2A >> 2;

変数「num」には0x2Aを右へ2つシフトした値が代入されます。この場合は次のような処理が行われます。

00000000 00000000 00000000 00101010  = 0x2A
-------------------------------------------
00000000 00000000 00000000 00010101  = 0x15  (1つシフト)
00000000 00000000 00000000 00001010  = 0x0A  (2つシフト)

0x2Aを右へ2つシフトすると00000000000000000000000000001010(0x0A)となります。右へシフトする場合、右側からはみ出たビットは捨てられます。そしてシフトによって空いた左側には、最上位ビットが1だった場合は1が詰められ、最上位ビットが0だった場合は0が詰められます。この結果、右シフトしても負の整数は符号がそのままで数値が1/2となります。

下記は最上位ビットが1だった場合の例です。

var num;
num = 0xFF00002A >> 2;

変数「num」には0xFF00002Aを右へ2つシフトした値が代入されます。この場合は次のような処理が行われます。

11111111 00000000 00000000 00101010  = 0xFF00002A
-------------------------------------------------
11111111 10000000 00000000 00010101  = 0xFFF00015  (1つシフト)
11111111 11000000 00000000 00001010  = 0xFFC0000A  (2つシフト)

右へシフトした時に空いた最上位ビットには、シフトする前が1だったので1で詰められています。

右シフト(符号無し)

「>>>」演算子は対象の値を指定した数だけ右へシフトします。「>>」演算子との違いはシフト前の最上位ビットが何であっても右へシフトした時に一番左のビットは常に0で詰めらという点です。次の例を見てください。

var num;
num = 0xFF00002A >>> 2;

変数「num」には0xFF00002Aを右へ2つシフトした値が代入されます。この場合は次のような処理が行われます。

11111111 00000000 00000000 00101010  = 0xFF00002A
-------------------------------------------------
01111111 10000000 00000000 00010101  = 0x7FF00015  (1つシフト)
00111111 11000000 00000000 00001010  = 0x3FC0000A  (2つシフト)

0xFF00002Aを右へ2つシフトすると00111111110000000000000000001010(0x3FC0000A)となります。この演算子の場合は、右シフトによって値を1/2にするということよりも純粋にビットを右へシフトさせたい場合などに使用されます。

サンプルコード

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

<!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/script9_1.js">
</script>

</body>
</html>
var num;

num = 0x15 << 2;
document.write("<p>0x15 &lt;&lt; 2 = " + num + "</p>");

num = 0x2A >> 2;
document.write("<p>0x2A &gt;&gt; 2 = " + num + "</p>");

num = 0xFF00002A >> 2;
document.write("<p>0xFF00002A &gt;&gt; 2 = " + num + "</p>");

num = 0xFF00002A >>> 2;
document.write("<p>0xFF00002A &gt;&gt;&gt; 2 = " + num + "</p>");

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

p9-1

演算結果が10進数で表されているので分かりにくいのですが、10進数の84は16進数で0x54、10進数の10は16進数で0x0A、10進数の-4194294は16進数で0xFFC0000A、10進数の1069547530は16進数で03FC0000Aです。

( Written by Tatsuo Ikura )