ビット演算子は、データやハードウェアとの低レベルの操作を便利にするためにC言語に導入されました:レジスタの設定、マスキング、2の冪による乗算と除算。これらの動作ルールは、8ビットおよび16ビットプロセッサの時代に確立されました。
signed型のシフトでしばしば間違いが発生します。結果は実装(算術シフトまたは論理シフト)によって異なり、タイプのサイズの境界を越えた場合にも問題が生じます。エラーはデータの破損、不正確な計算、未定義の動作を引き起こす可能性があります。
左シフト(<<): 値を2のk乗で乗算することと同等です(a << k)。常に右側にゼロを詰めます。
右シフト(>>): unsigned値の場合、左側にゼロを詰めます(論理シフト)。signedの場合は、符号ビットで埋める場合もあれば、ゼロで埋める場合もあります(動作はコンパイラによって異なります)。
例:
unsigned int x = 5; // 0000 0101 unsigned int y = x << 1; // 0000 1010 == 10 int z = -4; // 1111 1100(8ビットの場合) int w = z >> 1; // 1111 1110 (-2) または 0111 1110(実装に依存)
主な特徴:
負の数を右にシフトするとどうなりますか?
結果は実装に依存します。最も一般的には符号を保持する算術シフトになりますが、標準ではこれを保証していません。
型のビット数より多くシフトした場合の結果はどうなりますか?
未定義の動作です。例えば、1 << 32は32ビット型の場合、何が返ってくるかわからず、プログラムがクラッシュする可能性があります。
浮動小数点数にビット演算子を使用できますか?
いいえ、標準のfloatやdouble型はビット演算をサポートしていません。整数型のみです。
プログラマがマスクを生成するためにintを32シフトしました—一部のプラットフォームでは0になり、他のプラットフォームでは認識できない値になりました。
利点:
欠点:
代わりにunsigned値を使用し、マクロでビット数をマスキングし、明確な文書とsizeofを使ったタイプの長さのチェックを行いました。
利点:
欠点: