理解しにくいシフト演算について解説!基本情報技術者試験対策のポイント

計算式と木の人形

コンピュータでは、どのように掛け算や割り算を処理しているのでしょうか。一度の計算で処理可能な足し算や引き算とは異なり、掛け算や割り算の処理は難しそうに思えます。

例えば、7×8をまともに処理しようとすると、7を8回足せば実施できますが、これが123×456であれば456回も足し算を行う必要があり、現実的ではありません。

コンピュータ上で効率的に掛け算や割り算を実施するためには、シフト演算を用います。この記事では、シフト演算の実施方法や種類についての解説を行います。

目次

コンピュータ上での乗算・除算の方法とは

上述の通り、掛け算を実施する際にそれを分解して足し算にすることは現実的ではありません。その代わりの方法として、コンピュータ上では掛け算や割り算はビット列をずらすことで実現されます。

ビット列をずらす」という言葉のイメージが付きにくいかもしれません。

例えば、「12345」という十進数があったとして、これの数字を一つ左にずらして0をつけると、「123450」となります。これは、数値を10倍していることになりますね。一方で、「12345」を一つ右にずらすと、「1234.5」となります。これは、数値を10で割っていることになります。

コンピュータ上では、ご存じのように0と1という2進数ですべての数値が処理されています。

ここで、「1110」(10進数で14)という数値があったとして、これを左に一つずらして0を付けると「11100」(10進数で28)となり、数値が2倍されていますね。一方で、「1110」を右に一つずらすと「111」(10進数で7)となり、数値が1/2となっています。

このように、数値のビット列を左にずらせば掛け算、右にずらせば割り算となります。2進数であれば、1ビット左右にずらせば2の掛け算や割り算となり、2ビットずらせば4の掛け算や割り算となります。

このような計算処理を、シフト演算といいます。

論理シフト演算

以下では、具体的なシフト演算の手法について解説します。

まず紹介するのは論理シフト演算です。論理シフト演算とは、シフト演算のうち符号を考慮しない計算のことです。符号を考慮しないため、+と-が混在するような計算は実施できず、基本的には正の値を対象に行われるものです。

掛け算を行うためには、論理左シフト演算を用います。論理左シフト演算では、掛ける分だけ左にビット列を移動させます。2倍であれば1ビット、4倍であれば2ビット、8倍であれば3ビットずらすことで、乗算を実現します。

例えば、「00111100」(10進数で60)という数値に対して2ビット左にずらすと、「11110000」(10進数で240)となり、数値が4倍されます。

一方で割り算を行うためには、論理右シフト演算を用います。論理右シフト演算では、割る分だけ右にビット列を移動させます。1/2であれば1ビット、1/4であれば2ビット、1/8であれば3ビットずらすことで、除算を実現することができます。

例えば、「00111100」(10進数で60)という数値に対して2ビット右にずらすと、「00001111」(10進数で15)となり、数値が1/4されます。

算術シフト演算

もう一つのシフト演算方法に、算術シフト演算というものがあります。算術シフト演算とは、シフト演算のうち符号を考慮するものです。コンピュータ上では先頭ビットが符号を示すため、算術シフト演算では先頭ビット以外をシフトさせます。

また、負数同士の掛け算、割り算であれば、符号を反転させる処理も同時に行います。

算術左シフト演算では、掛ける分だけ先頭を除き左にビット列を移動させます。2倍であれば1ビット、4倍であれば2ビット、8倍であれば3ビットずらすことで、乗算を実現します。

例えば、数値域を「128~-127」と設定した1バイトの数値である「10011100」(10進数で-28)があるとします。この数値の先頭である「1」は符号を表す数字であり、0であれば+、1であればマイナスを表します。

この「10011100」に対して、先頭を除き左に2ビットずらすと、「11110000」(10進数で-112)となり、符号を変えずに4倍できていることが分かります。

一方で、算術右シフト演算では割る分だけ先頭を除き右にビット列を移動させます。1/2であれば1ビット、1/4であれば2ビット、1/8であれば3ビットずらすことで、除算を実現します。

同様に「10011100」(10進数で-28)に対して先頭を除き右に2ビットずらすと、「10000111」(10進数で-7)となり、符号を変えずに1/4できていることが分かります。

2の乗数以外の乗算・除算

ここまで紹介した例は、すべて2の倍数の値を掛けたり割ったりするものでした。それでは、5や7などの2の乗数以外の乗算・除算を実施する場合はどのように行うのでしょうか。

2の乗数以外の乗算・除算を実施する場合、その値を2の乗数に分解したうえで計算を実施します。

例えば、「00011100」(10進数で28)に対して6を掛ける場合はどうするのでしょうか。まずは、6を2の乗数に分解します。6は、「2の2乗(=4) + 2の1乗(=2)」と分解できます。よって、「00011100」に6を掛けたい場合は、「00011100」に対して4を掛けたものと2を掛けたものを足し合わせればよいことが分かります。

具体的には以下の通りとなります。まず、「00011100」を左に2ビットずらすと「01110000」(10進数で112)となります。次に、「00011100」を左に1ビットずらすと「00111000」(10進数で56)となります。これらを足し合わせると、「10101000」(10進数で168)となり、確かに28に6を掛けたものであることが分かるでしょう。

まとめ

この記事では、基本情報技術者試験を受けようとされている方に向けて、シフト演算に関する内容の解説を行いました。特にコンピュータに慣れていない方にとっては、シフト演算の考え方は分かりにくいものかもしれません。

しかし、この記事で紹介したようにシフト演算の考え方は決して難しくありません。基本情報技術者試験でもパターンさえ押さえておけば確実に正解できる分野ですので、貴重な得点源として確保しておくことをおすすめします。