主な用途は、特定のビットに関して定義されたより大きなアイテムの一部がある場合です。
わかりやすい例として、色を保持する 32 ビットの数値を考えてみましょう。赤、緑、青にそれぞれ 8 ビット、(おそらく) アルファ (この色/ピクセルの透明度を示す) に残りの 8 ビットを使用します。16 進数では、数字は次のようになります。
AARRGGBB
(つまり、各コンポーネントの 2 桁または 8 ビット)。
そのようなものを取り、次のようなコンポーネントに分割できます。
red = color & 0xff;
green = (color >> 8) & 0xff;
blue = (color >> 16> & 0xff;
alpha = (color >> 24) & 0xff;
逆に、コンポーネントをまとめることができます:
color = (alpha << 24) | (blue << 16) | (green << 8) | red;
また、ハードウェアを扱うときは、通常、このようなビット操作を行うことになります。たとえば、あるものに 5 ビット、別のものにさらに 2 ビット、3 番目のものに 6 ビットなどを割り当てる 16 ビット レジスタがあるとします。これらのいずれかを変更する場合は、上記の色の例のように行います。1 つのフィールドを表すビットを分離し、必要に応じて変更してから、他のビットと一緒に戻します。
もう 1 つの (まったく関係のない) アプリケーションは、ハッシュのようなものです。ここでは通常、そのようなフィールドはありませんが、入力のバイトによって少なくともある程度影響を受ける出力のすべてのビットで、入力のいくつかのバイトが単一の出力を生成するようにします。それを達成するために、ほとんどの場合、入力の各バイトが結果のさまざまな部分に影響を与える可能性が少なくともあるように、ビットをシフトすることになります。
古いコードのかなりの部分がビット シフトを使用して 2 の累乗で乗算または除算を最適化していますが、これは通常、最新のハードウェアとコンパイラでは時間の無駄です。既存のコードでそれを確認し、それが何を達成しようとしているのかを理解する必要がありますが、その例をエミュレートしようとしないでください。