コンピュータの内部計算で頻出する「ビット列をずらす操作(シフト演算)」。
今回は、似ているようで役割が全く異なる「論理シフト」と「算術シフト」
その仕組みと使い分けについて進めます
1. 論理シフトと算術シフトの違い
この2つの最大の違いは、符号(プラス・マイナス)を気にするかどうかです。
コンピュータは数値を2進数のビット列(0と1の並び)で管理しています。
このとき、先頭のビットを「符号」として扱うか、ただの「データ」として扱うかで、選ぶべきシフト方法が変わります。
・論理シフト
符号を無視する(ビットの模様としての移動)
・算術シフト
符号を維持する(数値計算としての移動)
2. 論理シフト
論理シフトは、データを「符号のない単なるビットの並び」として扱います。
画像データやフラグ操作、符号なし整数の処理に使われます。
ルールは簡単で「空いた場所には常に 0 を入れる」だけです。
・左論理シフト
左にずらし、右端の空いた場所に 0 を入れる。
・右論理シフト
右にずらし、左端の空いた場所に 0 を入れる。元のデータがどんな値であっても、
ずらして空いた隙間は無条件で 0 で埋められます。
【例題】
8ビットのデータ 11001011 を、右に2ビット論理シフトしてください。
【解説】
-
データ全体を右に2つずらします。
-
右側にはみ出した
11は捨てられます。 -
左側の空いた場所には、無条件で
00を入れます。
元データ:
11001011
↓
結果 :00110010
このように、元の値が何であれ、空いた隙間は 0 で埋められます。
3. 算術シフト (Arithmetic Shift)
算術シフトは、データを「符号付きの数値(プラス・マイナス)」として扱います。
先頭のビット(符号ビット)が 0 ならプラス、1 ならマイナスを表しますが、
この符号を壊さないように配慮してシフトするのが特徴です。
特に重要なのが「右算術シフト」です。
・右算術シフト
右にずらした際、左端(先頭)の空いた場所には「元の符号ビットと同じ値」を入れます。
元がプラス(0…)なら、0 を補充。元がマイナス(1…)なら、1 を補充。
・左算術シフト:左にずらす際は、通常右端に 0 を入れます(論理シフトと同様になりますが、符号ビットが変わるとオーバーフローとなります)。これにより、マイナスの数値を割ってもマイナスのまま計算を続けることができます。
【例題】
負の整数 10001100 (-116) を、右に2ビット算術シフトしてください。
【解説】
-
先頭のビットを見ます。
1なので、これはマイナスの数です。 -
データ全体を右に2つずらします。
-
左側の空いた場所には、元の符号ビットと同じ
1を入れます(ここが論理シフトとの違いです)。
元データ: 10001100 (先頭が1)
↓
結果 : 11100011 (空いた場所に1を補充)
【計算の意味】
右に2ビットシフトすることは「$\div 4$」を意味します。
符号ビットをコピーして埋めることで、マイナスの値を保ったまま割り算の結果(-116 $\div$ 4 = -29)が得られます。
今回のまとめ
| 用語 | 意味 |
|---|---|
| 論理シフト | 符号を無視してずらす操作。空いたビットには常に「0」を入れる。画像処理や符号なし整数に使われる。 |
| 算術シフト | 符号(±)を維持してずらす操作。右シフト時は空いた場所に「符号ビットと同じ値」を入れる。通常の数値計算に使われる。 |
| 計算の効果 | 左右にずらすことで、かけ算・割り算を超高速に行える。左に$n$ビット = $2^n$ 倍右に$n$ビット = $1/2^n$ にする(割り算) |
| 覚え方 | 「算術」は「算数」なので、プラスマイナスを大切にする、と覚える。 |