見出し画像

【FE5問】シフト演算(基本情報技術者試験)

コンピュータの電子回路では1ビット単位で処理をします。

今回のシフト演算は、データの位置をビット単位でずらす処理です。

病院などで椅子に並んで座って待っていたら、前の人が診察に行けば、他の人は席をずらして座っていくようなものです。

シフト演算は、掛け算と割り算をするときに使われます。

シフト演算は、数を右や左にずらすだけなので学び始めるのは簡単です。しかし、細かくみると論理シフトと算術シフトがあり、補数との絡みもあるため、奥深いです。

後半は正直とても難しい問題になってしまいますが、最初の問題だけでも正解できるようになれば、合格を助けてくれますよ。


それでは始めましょう!






シフト演算は掛け算と割り算


シフト演算は、コンピュータの掛け算・割り算の役目をします。

私たちも10進数でシフト演算してるんですよ。

50に10を掛け算すると500、50を10で割ると5ですよね。

今リアルに50×10、50÷10を筆算でしましたか?

50に0を追加して500、50の0を消して5にしませんでしたか?

これがシフト演算です。

  • 左にずらせば掛け算:50→500

  • 右にずらせば割り算:50→5

10進数で10を掛け算するときは左ずらし(左シフト)
10進数で10で割り算するときは右ずらし(右シフト)


2進数でも考えてみます。

  • 2進数の10を左にずらせば100:10進数の2→10進数の4

  • 2進数の10を右にずらせば1:10進数の2→10進数の1

2進数を左シフトすると、×2したこと
2進数を右シフトすると、÷2したこと


では、「2進数の10」(10進数の2)を、3倍するときはどうするか。

1ビット左シフトして2倍して、元の数を足し算して3倍に持っていきます。

10→1ビット左シフトして100→元の数10を足して110。

「2進数の110」は「10進数の6」です。元の数は「2進数の10」(10進数の2)なので、ちゃんと3倍されていますね。

コンピュータでの掛け算と割り算は、シフト演算と足し算で実現できます




コンピュータの四則演算


コンピュータでの四則演算(+, -, ×, ÷)は以下のように行われます。

  • 足し算:加算回路

  • 引き算:加算回路(補数を使う)

  • 掛け算:左シフトと足し算

  • 割り算:右シフトと足し算

引き算は「補数」を使えば足し算で実現できます。詳しくは >補数の解説Note

掛け算と割り算はシフトだけでは、×2, ×4, ×8や÷2, ÷4, ÷8しかできないので、足し算と組み合わせます。

例えば、×3をするなら、左シフトで×2をして、元の数を足し算して×3を計算します。




問題演習(シフトによる掛け算)


2進数10110を3倍したものはどれか。

ア:111010
イ:111110
ウ:1000010
エ:10110000

ITパスポート試験 平成21年春問64より

正答はウ。


2つの解き方があります。

  • 2進数を10進数にして3倍して、2進数に戻す

  • 2進数を左1ビットシフトして、(シフト前)の自分自身をを足す

過去問道場さんの図解が分かりやすいです。


10進数経由の方。「10110」を10進数にすると、16+4+2=22。3倍して66。2進数に戻して「1000010」。

シフトの方。「10110」を1ビット左して「101100」、これで2倍になっています。「10110」を足して「1000010」。



レジスタに格納されている正の整数xを10倍する操作はどれか。なお、シフト演算による「桁あふれ」は起こらないとする。

ア:xを2ビット左シフトし、xを加算、1ビット左シフトする
イ:xを2ビット左シフトし、xを加算、2ビット左シフトする
ウ:xを3ビット左シフトし、xを2ビット左シフトした値を加算
エ:xを3ビット左シフトし、xを加算、1ビット左シフトする

基本情報技術者試験 平成20年春午前問04より改訂

正答はア。

いろんな手順が考えられるので、選択肢から迫っていってみます。

  • ア:正しい。2ビット左シフトで4倍、xを加算して5倍に、1ビット左シフトで2倍されるので10倍に。

  • イ:2ビット左シフトで4倍、xを加算して5倍に、2ビット左シフトで4倍されるので20倍に。

  • ウ:3ビット左シフトで8倍、xを2ビット左シフトした値は4倍の値、両者を足して12倍。

  • エ:3ビット左シフトで8倍、xを加算して9倍に、1ビット左シフトで2倍されるので18倍。

他にも、xを3ビット左シフト(8倍)して、xを2回加算するのもできますね。または3ビットシフト後に、xを1ビットシフトした値を加算でもできます。




2種類のシフト


シフト演算には2種類あります。

論理シフトはシンプルですが、算術シフトは注意してください(特に右シフトの場合)。

  • 論理シフト(0を追加する)

    • 左シフト:010→100 

    • 右シフト:010→001, 110→011

  • 算術シフト

    • 左シフト:011→010, 101→110(最上位ビットは変わらない) 

    • 右シフト:010→001, 110→111(追加するビットが違う)

左の算術シフトでは、最上位ビットはそのままにします。

「0」11を、左シフトすると「0」10。「1」01を、左シフトすると「1」10。

右の算術シフトでは、最上位ビットと同じ値を追加します。

「0」10の最上位ビットは「0」なので、右シフトしたら「00」1。「1」10の最上位ビットは「1」なので、右シフトしたら「11」1になります。

資格試験では、右の算術シフトで引っ掛けてくるので注意してください。




論理シフトの問題演習


論理シフトなので、ずらして、空きに「0」を追加するだけでOKです。

16進数表記してABCDを32ビットレジスタに格納している。2ビット右に論理シフトした時の値はどれか。

ア:2AF3
イ:6AF3
ウ:AF34
エ:EAF3

基本情報技術者試験 平成25年秋午前問02

正答はア。

16進数は4ビットなので、問題文の2ビットシフトは中途半端です。よって、1ビットごとに見るために2進数に変換して考えます。

16進数を2進数に変換する方法は2通り。

  • 16進数→10進数→2進数

  • 16進数4桁→2進数1桁


楽なのは2番目。

16進数のABCDの「A」「B」「C」「D」をそれぞれ考えます。

  • Aは10なので、1010

  • Bは11なので、1011

  • Cは12なので、1100

  • Dは13なので、1101

よって2進数では「1010 1011 1100 1101」。


右に2ビット論理シフトします。論理シフトでは、空いたビットは「0」で埋めるのでシンプル。

「0010 1010 1111 0011 01」右に2桁あふれた「01」が消えて、「0010 1010 1111 0011」。


2進数4桁を16進数1桁に変換します。

  • 0010は2なので、2

  • 1010は10なので、A

  • 1111は15なので、F

  • 0011は3なので、3

よって「2AF3」となり、正答はア。




算術シフトは「補数」対応のため


なぜ算術シフトがややこしいことをするのかは、シフト演算で「補数」を崩したくないからです。

例えば、10は「-2を意味する補数」ですが、右に論理シフトしてしまうと、01になり「+1」を意味する数になってしまいます。

右に算術シフトすれば、10→11となり。11は「-1を意味する補数」なので、-2を右シフト(÷2)して-1になった、と計算的なツジツマが合います。


左の算術シフトも同じです。

例えば、01は「2進数の1」ですが、左に論理シフトすると10になり、最上位が「1」なので補数になってしまいます。10は「-2を意味する」補数なので、1×2が正しく計算できません。

よって補数を使う場合は、論理シフトではなく算術シフトを使うべきなのです。




難しい問題演習(算術シフト)


8ビット2進数「1101 0000」を右に2ビット算術シフトし、0001 0100から引き算した値はどれか。なお、負の値は補数表現を用いる。

ア:0000 1000
イ:0001 1111
ウ:0010 0000
エ:1110 0000

基本情報技術者試験 平成24年秋午前問01より改訂

正答はウ。


まずなるべく10進数で考えて、状況を教えますね。

「1101 0000」は「補数」なので「普通の数」に戻します。

不思議なことに「補数→普通の数」の変換手順は「普通の数→補数」と同じです。>補数のNote

1101 0000を、各桁ビット反転して0010 1111、+1して0011 0000。10進数にすると32+16=48。つまり1101 0000は-48を意味しています。

問題文で「右に2ビットシフト」するので、-48÷4=-12。

一方で問題文の「0001 0100」は、10進数にすると16+4=20。

問題文の引き算をすると、20 - (-12) = 32。2進数にすると「0010 0000」。

まとめると、11010000(-48)を2ビット右シフトして(-12)、00010100(20)から-12を引くので、32になります。


では出題者がやって欲しかった解法をしてみます。

まず算術シフトについて。

  • 左シフト:左にずらし、右端(最下位)には0を追加。ただし最上位は変えない

  • 右シフト:右にずらし、左端(最上位)には元最上位と同じ値を追加

例えば、「0」10を1ビット右シフトすれば「00」1。「0」を左端に追加しています。「1」10を1ビット右シフトすれば「11」1。「1」を左端に追加しています。

さて、1101 0000を2ビット右に算術シフトすると、最上位は1なので左端に1を追加しつつずらし、1111 0100。

00010100 - 1111 0100をしたいです。

1111 0100の最上位が「1」なので補数です。「普通の数」に変換します。1111 0100→0000 1011→0000 1100、10進数の12。よって1111 0100は「10進数の-12を意味する補数」です。

00010100(10進数の20)- 1111 0100(10進数の-12) = 20 - (-12)=32。

32を2進数にして、

これで、正解できます。




難しい問題演習の補強


もう少し深めます。

コンピュータ内部での四則演算の手順は以下。

  • 足し算:加算回路

  • 引き算:補数にして足し算で実現

  • 掛け算:左に算術シフト

  • 割り算:右に算術シフト

00010100 - 1111 0100ですが、00010100 + (-1111 0100)、00010100 + (1111 0100の補数)で計算してみます。コンピュータには加算回路しかないので、引き算は補数を使った足し算でします。>補数の解説Note

1111 0100の補数は、反転して0000 1011→+1して0000 1100。つまり10進数の12。

0001 0100 - 1111 0100 = 0001 0100 + 0000 1100 = 0010 0000。10進数の32になりました。


右の算術シフト、補数にして足し算は、とてもややこしいですが、「数の操作」をそのまますれば良いのです。




問題演習(データの抽出)


シフト演算は、掛け算割り算だけでなく、データの抜き出しにも使われます。

16ビットの2進数nをレジスタに格納し、下位の桁から順番にスタックに格納するために、次の操作を4回繰り返す。a, bに入る語句はどれか。なお、xxxx(16)は16進数を示す。
手順
1:【a】をxに代入する
2:xをスタックにプッシュする
3:nを【b】論理シフトする

選択肢:a:b
ア:n AND 000F(16), 左に4ビット
イ:n AND 000F(16), 右に4ビット
ウ:n AND FFF0(16), 左に4ビット
エ:n AND FFF0(16), 右に4ビット

基本情報技術者試験 平成23年秋午前問01より改訂

正答はイ。


イの処理について確認をしてみます。

試しに16進数をABCDとします。

  • Aは10なので、1010

  • Bは11なので、1011

  • Cは12なので、1100

  • Dは13なので、1101

よって、16進数ABCDは、2進数では「1010 1011 1100 1101」。

イの「000F」は、2進数では「0000 0000 0000 1111」。

両者のANDをとって、「0000 0000 0000 1101」。この数をスタックにプッシュします。

次に元のデータを右に4ビットシフトして「0000 1010 1011 1100」。プッシュしたデータ「1101」が消えましたね。


2回目も同様に、ANDとって「0000 0000 0000 1100」をスタックに入れて、元データを4ビット右シフトして「0000 0000 1010 1011」。

3回目。ANDとって「0000 0000 0000 1011」をスタックに入れて、元データを4ビット右シフトして「0000 0000 0000 1010」。

4回目。ANDとって「0000 0000 0000 1010」をスタックに入れて、元データを4ビット右シフトして「0000 0000 0000 0000」


以上で、下位から「1101」「1100」「1011」「1010」を順番にスタックに入れることができました。




まとめ


お疲れ様でした!

シフト演算は論理シフトならすごく簡単でしたね。

それだけでも充分得点源になりますが、算術シフトも一応覚えておいてください。左シフトでは先頭を変えない、右シフトでは最上位ビットをコピペする、です。



他にも計算問題のNoteはたくさん公開していますので、興味があったら覗いていってくださいね。

それでは!

\力試しは修了試験で!4回分の解説です/


p.s. 普段は >> 専門学校とIT就職のブログ << をやってます。

でわでわ(・ω・▼)ノシ


この記事が参加している募集

#スキしてみて

527,181件

学習方法・問題特集のNoteは全て無料提供を続けます▼ もしご覧になったNoteが有益だったり、私の志に共感されたりしましたら、サポート頂けますと励みになります▼ もちろんコメントでも結構です(・ω・▼)ノシ