ビットシフトを使い、高速な計算を実現する
2進数の桁を左右にずらして行う計算手法です。シンプルなので高速に計算できます。
2進数のビット(桁)を左右にずらすことで、
2の累乗による掛け算・割り算をシンプルに行う演算手法。
10進数で考えると、桁をずらすことが10倍や1/10倍になるのと同じです。
123 << 1 → 1230(×10) 123 >> 1 → 12.3(÷10)
この「桁をずらす=何倍・何分の1」という感覚を、
2進数の世界でも同じように応用するのが「シフト演算」です。
シフト演算は、2進数だからこそ成り立ちます。
シフト演算は、2進数のビット列を左右にずらす操作をします。
桁を1つずらす操作は、10進数における「10倍」や「10分の1」の計算に相当します。
2進数の場合、ビットを1つ左にずらすと値は2倍に、右にずらすと2分の1になります。
例: 10(2進数: 1010)のシフト演算
// 1ビット左シフト (2倍) 1010 << 1 → 10100 (20) // 1ビット右シフト (1/2) 1010 >> 1 → 0101 (5)
シフト演算は、コンピュータが最も得意とするビット操作のため、非常に高速です。
8進数や16進数で表記されることもありますが、実際の計算は必ず2進数で行われます。
論理シフトは、空いた桁に「0」を詰める方法です。負の数には対応していません。
→ 桁を左右にずらし、空いた桁に「0」を詰める方法。
左シフトで×2、右シフトで÷2 になります。
元の値: 5
↓ 1ビット左シフト
結果: 10
元の値: 5
↓ 2ビット左シフト
結果: 20
元の値: 8
↓ 1ビット右シフト
結果: 4
元の値: 8
↓ 2ビット右シフト
結果: 2
※ 論理右シフトでは、常に左端に 0 が入ります。
※ 負の数には対応していません。
算術シフトは、左端の符号ビットを固定したまま右シフトする方法で、負の数も扱えます。
→ 左端の符号ビットを固定したまま右シフトする方法。
元の値: -4
↓ 1ビット算術右シフト
結果: -2
最上位ビットに1が入るとオーバーフロー(桁あふれ)し、負の数になることがあります。
左シフトは通常「×2」「×4」のように値を大きくしますが、
符号付きの整数を左シフトして、最上位ビットに1が入ると、
符号が反転して“負の数”として扱われることがあります。
これは「桁あふれ(オーバーフロー)」と呼ばれる現象です。
64(10進) = 01000000(2進) ↓ << 1(左に1ビットシフト) → 10000000(2進) = -128(10進)
本来なら「64 × 2 = 128」のつもりだったのに、
8ビットの範囲では128を表せないため、結果が -128 になる!
→ これは計算ミスではなく、ビット数の限界による仕様上の“落とし穴”です。
試験や参考書の問題文では、以下のような補足がつくことがあります:
※ オーバーフローが発生した場合の動作は考慮しないものとする。
この場合は、ビット数による符号反転や桁あふれの影響を無視し、
純粋な「×2」や「÷2」として計算する必要があります。
つまり、64 << 1 は -128 ではなく 128 を選ぶのが正解になる ということです!