Transcript for:
シフト演算の基礎と応用

みなさんこんにちは本日は基礎理論コース第4回としてシフト演算を勉強していきます前回のコースでは二進数の足し算引き算を勉強しましたが今回は掛け算割り算を勉強していくイメージですそれでは早速内容を見ていきましょうまずシフト演算とは何かというと二進数を表すビット列を左右にずらすことを指しますわかりやすいように最初に実心数で考えてみましょう73. 6という実心数を10倍もしくは1分の10倍するとき当然ですが10倍したら73610分の1倍したら7.36になりますね私たちは当たり前のようにこの計算をしていますがよく見てみると桁を左に1つずらすと10倍右に1つずらすと10分の1倍になっているということですねつまり10進数では桁がずれると値が10倍になっています10進数の場合は桁の重みの基本となる数つまり奇数が10なので桁がずれると10倍になるというのは納得いくと思いますそしてこれは2進数でも全く同じことが言えます2進数の場合は桁の重みの基本となる数は2ですので桁が1つ左にずれると2倍2つ左にずれると2の2乗つまり4倍となりますまた桁が1つ右にずれると1分の2倍、2つ右にずれると2の-2乗、つまり1分の4倍となります。 これを公式に落とし込むと、左にn個ずれると値は2のn乗倍に、右にn個ずれると値は2の-n乗倍となります。 そしてこの桁をずらすことをシフト演算と言います。 ただしこのシフト演算にはロンリシフトと算術シフトという2つの方法がありますのでそれぞれどのような操作をするのか解説していきますまず論理シフトですがこれは符号を考慮せずにシフト操作をすることです前回のコースで符号ビットの説明をしましたが覚えているでしょうか2進数の一番最初のビットを符号としてみなし符号ビットが0の時は正1の時は負とするんでしたねそのような符号ビットを考慮せず単純に桁をずらすことを論理シフトと言いますちなみに符号ビットを考慮しなくてよいのかどうかは私たちやコンピューターは二進数を見ただけでは判断できないので今回は符号を無視して論理シフトしなさいとどこかで指定されますでは論理シフトの方法を説明していきますまずは左シフトつまり掛け算を説明します例として8ビットで二進数を表すデータを論理シフトするケースを考えます今回00101010という2進数を用意しましたこれは10進数で表すと42ですねそしてこれを2ビット左シフトするということは42を2の2乗倍つまり4倍するということです10進数で考えると42を4倍した値は168ですので2進数を2ビット左にロンリシフトした場合にちゃんと168になるのか最後に確認してみましょう論理シフトの方法ですが、まずは各桁を指定されたビット数左にずらします。 今回は2ビットの論理シフトなので、各桁を2ビットずつ左にずらします。 すると2ビットずらしたので、左側の2ビットははみ出てしまい、右側の2ビットは空白になってしまいました。 このはみ出た部分は無視して、最後の空いたスペースには0を詰めることで、2ビット左論理シフトをすることができます。 実際にやってみるとこのように10101000となりましたこれを10進数に換算してみると確かに168でしたので2ビット論理シフトをすれば値が4倍されたことが分かりましたでは今度は3ビット左へ論理シフトしたらどうなるか見てみましょうそうすると42を2の3乗倍つまり8倍するので336になるはずです先ほどと同様に桁をずらしていきます今回は3ビットと左にシフトするので3つ桁をずらしますそしてはみ出たスペースを無視して空いたスペースに0を入れてロンリシフトが終了しましたしかし得られた2進数を10進数に直してみると80になっており336と一致していませんこれはなぜなのでしょうか理由は42を8倍した値は8ビットで表せる範囲を超えてしまっているので正しい数値が表現できなかったんです前回のコースで8ビット符号なしに真数が表せる数値は1から255と説明しますつまり42を8倍した336はそもそも8ビットで表現することができず表現したかったらもう1ビット加えて9ビットのデータで表現する必要があるんですこのようにそのビット数で表せる数値の範囲を超えてしまう現象をオーバーフローと言いますこのオーバーフローはどのように判断するかというとロンリシフトの場合は1がはみ出た時にオーバーフローを起こしたと判断することができます今回確かに1がはみ出ていますねつまり00101010の3ビット左シフトは8ビットのデータでは表現することができないということになりますでは続いて右論理シフトを見ていきましょう右にシフトするので割り算ということになります例として01001000という二進数を用意しましたこれは10進数で表すと72です。 これを2ビット右シフト、つまり2のマイナス2乗しますので、4で割り算することになります。 10進数で考えると18になりますので、右シフトした後にちゃんと18になっているか今回も確認していきましょう。 やり方は先ほどの左シフトと同様で、右に指定されたビット数ずらしていきます。 今回は2ビット右シフトなので、右に2つ桁をずらしていきますそうすると右側の2桁がはみ出し左側の2桁が空白スペースになってしまいましたそしてこのはみ出た部分を無視して空白スペースを0で埋めることでロンリ右シフトが完了します得られた2進数を10進数に直すと確かに18となっているので正しく計算できたことが分かりましたでは続いて73を2ビット右シフトした時を見ていきましょう73を4で割ると答えは18余り1となりますこの余りはどのように表現されるのか見ていきましょう先ほどと同様に桁を右に2つずらしてはみ出たスペースは無視空いたスペースに0を詰めますすると2進数は00010010となり先ほどと同様に割り算の答えとなる18を得ることができました先ほどと異なる点は1がはみ出ていることです実はこのはみ出した部分というのは割り算の余りを示しており、今回は01がはみ出ているので余りが1であることを意味しています。 つまり2ビット右シフトした結果は小が18、余りが1であり、実際に73 4の答えと一致していますね。 左論理シフトの場合は1がはみ出してしまうとオーバーフローとして計算ができなかったのですが、右論理シフトの場合は1がはみ出しても、それはただ割り算の余りを示しているだけで割り算の個体自体は算出できますでは続いて算術シフトを見ていきます算術シフトとは符号を考慮してシフト操作することです一番最初のビットを符号ビットと見出す場合はシフト操作の方法が論理シフトと異なりますのでその挙動を見ていきましょうまずは左の算術シフトつまり符号を考慮した掛け算を見ていきますなお負の数は2の歩数で表現していきます例として11101000という二進数を持ってきました一番最初のビットは符号ビットでこれが1ということはこの二進数は負の数を表していますこの数値を進数に直してみましょう2の歩数は再度ビット反転させて1をプラスすることでその元々の数値を得ることができると前回のコースで説明しましたではこの2の歩数で表現された2進数をビット反転して1をプラスしてみると24となりますつまりこれは24を2の歩数で表現した値なので10進数では-24となりますこれを2ビット左に30シフトするので値を4倍するつまり-96になれば良いということですねでは実際にシフト演算をしていきましょうやり方はまず符号ビットを無視して符号ビット以外の7個のビットを先ほどと同様に左に2つずらしますすると符号ビットは無視しているので左側2ビットがはみ出し右側2ビットが空白になってしまいましたここに論理シフトと同様はみ出したビットは無視して空白ビットに0を入れますなお論理シフトでは1がはみ出したらオーバーフローと言いましたが算術シフトでは1ではなく符号ビットと異なる数値がはみ出た時にオーバーフローを起こします今回だと符号ビットが1なので0がはみ出た時にオーバーフローとなります今は1しかはみ出ていないのでオーバーフローは起こしませんでははみ出た部分を無視して空白スペースに0を詰めるとこのようになりますそして最後に符号ビットをそのまま下に落とすことで算術シフトが完了します得られた2進数をビット反転して1をプラスすると96ですのでこれは96の2の歩数となっていますつまり10進数に直した時の値は-96で正しく計算が行われていることがわかりましたでは続いて先ほど説明した30シフトのオーバーフローの例を見ていきます今画面に見せた日進数を10進数に直すと-34ですこれを2ビット左に30シフトした時を見てみましょう-34を4倍すると-136ですが前回のコースでは符号付8ビット日進数が表現できる値の範囲は-128から127と説明したので-136は8ビットでは表現できずオーバーフローを起こすはずですでは本当にオーバーフローを起こすのか算術シフトしてみます符号ビットを固定して桁を2つずらすと0がはみ出てしまいました算術シフトの場合は符号ビットと異なる値がはみ出るとオーバーフローになると先ほど説明しましたので確かに今回オーバーフローを起こしていることが確認できましたでは最後に30シフトの右シフトを見ていきましょう。 画面の2進数を10進数に直すと-24です。 これを2ビット右シフトするので、4で割った-6となれば良いのですね。 では右シフトを行いましょう。 やり方がパターン化されてきましたが、符号ビットを固定して桁を右に2つずらします。 そしてはみ出た部分を無視するところまでは同じですが、30シフトの右シフトのみ、空いたスペースには0ではなく符号ビットを詰めます今回の符号ビットは1ですので空いたスペースに1を詰めてはみ出た部分を無視します最後に符号ビットをそのまま下に落として算術シフトが完了です実心数に直すと確かに-6ですので正しく計算されたことが分かりました符号ビットを詰める点だけ間違えないように注意してくださいちなみにはみ出たスペースが割り算の余りを示しているという点は論理シフトと同じです。 では最後にそれぞれの操作方法の特徴を整理しましょう。 論理シフトの左シフトでは空いたスペースに0を詰めます。 また1がはみ出たらオーバーフローです。 一方で算術シフトの左シフトでは空いたスペースに0を詰める点は同じで、符号ビットと異なる数値がはみ出たらオーバーフローとなります。 また論理シフトの右シフトでは空いたスペースに0を詰め、はみ出た部分は余りを意味します。 一方で算術シフトの右シフトでは空いたスペースに符号ビットを詰めます。 はみ出た部分は余りとして扱う点は同じです。 また参考として2のn乗倍以外の数値での計算方法を説明します。 論理シフトを使えば2倍、4倍、8倍など2のn乗倍の計算は簡単にできました。 これを活用すれば、例えば7倍などの計算もすることができます。 7というのは4たす2たす1ですので、2の2乗プラス2の1乗プラス2の0乗と言えます。 つまり、ある数に7を掛け算するというのは、ある数に2の2乗プラス2の1乗プラス2の0乗を掛け算することになります。 すると分配法則より掛け算と足し算をそれぞれ分解していきます。 そうすると最初の部分はある2進数を2ビット左にロンリシフトした値、次の部分は2進数を1ビット左にロンリシフトした値となります。 よって2ビット左にロンリシフトした値と1ビット左にロンリシフトした値と元々の2進数を足し算することで7倍の数値を得ることができます。 また割り算も似た考え方で計算することができます。 ただし2のn乗倍以外の数値の掛け算割り算はおそらくテストに出題されないと思うので参考程度で確認しておいていただければ大丈夫です本日の動画は以上となります皆さんお疲れ様でしたこのチャンネルでは基本情報技術者試験に合格するための対策講座を作成していますこれから試験を受ける予定の方はチャンネル登録をしていただけると動画が探しやすいのでおすすめですまた僕のモチベーションにもつながりますので動画が役に立ちましたら高評価チャンネル登録していただけると大変ありがたいですそれでは本日も最後までご覧いただき本当にありがとうございました試験合格に向けて一緒に勉強を頑張っていきましょう