算術シフトをあつかいます

  ターゲットの2進数は符号付きです

この算術シフトでは、符号ビットをも つ、符号付きの正の数や負の数をターゲットにします。つまり負数がコンピューター内部で補数表現されている場合を扱うのが、 算術(さんじゅつ)シフトといって 論理シフト(前ページでやりました)と区別しますよ。

簡単にするために、8ビット=1バイトで考えます。
補数表現ですから、最左端ビット(=先頭ビット)が符号ビットになり、
0のとき正の数、1のとき負の数です。

<2ビット左シフト説明図>

<2ビット右シフト説明図>

2進数の11101101 つまり
1110 1101
(2)= −19(10)について、
�〆犬烹吋咼奪函複韻韻拭縫轡侫箸垢襦�
�∈犬烹殴咼奪箸世吋轡侫箸垢襦�
�1Δ烹吋咼奪箸世吋轡侫箸垢襦�
�けΔ烹殴咼奪肇轡侫箸垢襦�
 その結果は、
 � �1101 1010 
 �◆�1011 0100
 �� 1111 0110
 �ぁ�1111 1011
 となります。

左の図では�△鉢い鮴睫世靴泙靴拭�

ここでシフトの大切なことをまとめます。

符号ビットはそのままにする。

あふれてはみ出たものは捨てる(すてる)。

空欄(空いたビット)には、左シフトのときは0を入れ、右シフトのときは、 符号ビットと同じものを入れる。


さて元の数は、10進数で −19(10)であり、
�,�ら�い泙任鯑韻犬�10進数で表すと、
 �,�、−38 (2倍になった)
 �△�、−76(4倍になった)
 ��が、−10(倍になった)
 �い�、−5 (倍) 等となっています。
ただし、���い琶�かる通り、はみ出したものの種類が少し影響しています。
10進数に直して眺めたらはっきり分かるように、
左シフトについては、1ビットだけ左シフトは2倍する、2ビットだけ左シフトは4倍 する、3ビットだけ左シフトは8倍する、4ビットだけ左シフトは16倍する、 ‥‥ということです。
右シフトについても、次々に 倍、 倍、 倍 、倍、‥‥ することです 。
このことは、算術シフトも論理シフトと同様ということです。

算術シフトの様子を電卓で見てみよう

上の例で、「−19」の2ビット左シフトしたものが「−76」となること、
2進数(2の補数表現 8ビット)で表すと
1110 1101(2) から 1011 0100(2)となることを電卓で確認(確かめ)できます。

windowsに用意されているプログラマ電卓ですが、
左図のように、ボタン選択は10進、Byte(=8ビット)として「−19」を入力しました。続けて 「Lsh」「2」「=」の操作で 右図「−76」が確認されます。
Lsh =Left Shift ,Rsh =Right Shift のようです。2進数への確認はいつでも2進ボタンの選択により自動表記されます。
 これを使って、うっかりミスなど発見できますよ m(^○^)m
 

シフト演算でかけ算をしてみよう

ここでは、10ビットの大きさで、算術シフトをあつかってみます。
左はしの10ビット目が符号ビットです。
8ビットの大きさでは、シフトにより直ぐにでもハングアップするのではないか(後で詳しく見てみます)。10ビットはそのためです。
  
○ 1 1 1110 1100(2) を10倍します。

             A=11 1110 1100
          A<<3=11 0110 0000 (8倍)
          A<<1=11 1101 1000 (2倍)
    --------------------------------
       10A = 11 0011 1000 (8倍+2倍)
10倍するということは、8倍+2倍と同じです。
つまり 3ビットの左シフト(8倍)と 
     1ビットの左シフト(2倍)を
  たす(加える)ことで得られます。

10進に直して確かめします。
   A= 11 1110 1100 = −20(10)
10A= 11 0011 1000 = −200(10)
正しい結果です。 

○ A=1
1 1110 1100(2) を 5倍します。
           
A=11 1110 1100 (1倍)
    A<<2=11 1011 0000 (4倍)
    -------------------------

         5A=11 1001 1100  (1倍+4倍)
11 1001 1100(2) = −100 (10) ですから正しい結果です。
先の結果 10A を1ビット右シフトしても 5A が得られる筈で、いろいろな考え方が出来ます。

○ 同様に(算術)シフトを利用して、3倍する、6倍する、7倍する、9倍する、11倍する、…などを計算してみましょう。こうなると、コンピュータは掛け算を知らなくてもいいことが分かります。

シフト演算であつかう範囲(大きさ、Box)について

おさらい
補数で表す符号付き2進数は
8ビットBox では、
 1
000 0000= −128(10)
   から 0111 1111= 127(10) まで
の範囲(大きさ)の数を扱います。

先のように、
10ビットまで Box を大きくすると、
     10 0000 0000= −512(10)
 から 01 1111 1111= 511(10) まで
と範囲が広がります。 シフト演算では、はみ出たものはポイ捨てするので、それ相当の大きさのBox(もの)を用意しておかないと、予想外のことが起こってしまいます。
<注意点*再掲>
2、4、8、16、32倍、‥は「ネズミ算」式にバンバン増えるので、Box が小さいと直ぐにパンクしてしまうのです。

ここは符号付きの数ですから、最左端は符号ビットであることに十分気を付けてください。

実際の情報処理試験問題から

 [問題1] 8ビットの2進数 11010000 を右に2ビット算術シフトしたものを, 00010100 から減じた値はどれか。ここで,負の数は2の補数表現によるものとする。

ア 00001000   イ 00011111 
ウ 00100000   エ 11100000  

平成24年の出題。
【答は ウ】です、次のページで解説します。

2の補数表現については、「負数/補数」1000ページを見て下さい。  

 [問題2] 10 進数の −100 を 2 の補数表現で 8 ビットのレジスタに記憶する。これを右に 3 ビット算術シフトした結果を 10 進数で表したものはどれか。

 ア −33   イ −13   ウ −12   エ 19
平成10年の出題です。

【答は イ】
次のページで解説します。

前ページの問題の答え


��  1 0011 0000   (10進では304です)
��  1     (10進でも 1です。アハハ)
�� 8倍+2倍 で 1011 1110  です。
  (10進で 190 です)
   いずれも、10ビットの大きさで考え、符号なしの数です。

<注意点*> Boxの大きさ

8ビットの大きさのBoxで、補数で表す符号付き2進数を考えてみます。
8ビット目が符号ビットです。
      A = 1110 1000 としましょう
 A<<1 = 1101 0000
 A<<2 = 1010 0000
 A<<3 = 1100 0000
  ------
 
となりますが、この 3ビット左シフトで、おかしなことが発生 しました!! 左の数を10進数で見てみると、
   A = −24
A<<1 = −48  (Aの2倍になっている good)
A<<2 = −96(Aの4倍になっている good)
A<<3 = −64 (あれ〜おかしやな ??? )
------
8ビット符号付き2進数では
−128(10)から127(10)までの 範囲の数を扱うから、 A<<3 では、この範囲であふれが生じて(10進正解は−192)、間に合わないのです。

あふれ⇔はみ出しについて 分かってきたこと

  元の数が最左端ビット=1のとき、つまり負の数の場合、
左シフトによって「1」がはみ出す時は「あふれ」は生じない。 「0」がはみ出す時「あふれ」が起きる。
 先頭から「1」を幾つか連続して並べて比較するとよく見えてきます。
 逆に、元の数が最左端ビット=0のとき、つまり正の数の場合、
左シフトによって「0」がはみ出す時は「あふれ」は生じない。 「1」がはみ出す時「あふれ」が起きる。