C#、およびVB(7.1以降)では、言語組み込みのシフト演算として、以下のシフト演算子が用意されています。 代入先を左オペランド(左項)とする複合代入演算子も用意されています。
シフト演算 | 演算子 | |
---|---|---|
C# | VB(7.1以降) | |
左シフト |
<< , <<= |
<< , <<= |
右シフト |
>> , >>= |
>> , >>= |
右シフト演算子は、左オペランド(左項・シフトされる値)が符号付き整数の場合は算術シフト(負数の場合は上位側ビットに1
、正数の場合は0
が補われる)となり、符号無し整数の場合は論理シフト(上位側ビットに常に0
が補われる)となります。 言い換えると、右シフト演算子では常に最上位ビット(符号ビット)と同じ値が補われます。 左シフト演算子では、常に0
が補われます。
C#におけるシフト演算子は、32ビットまたは64ビットの整数型(int
, uint
, long
, uint
)に対してのみ定義されています。 8ビット・16ビット整数型に対してシフト演算を行う場合、値は自動的にint
へ拡大変換された上でシフト演算が行われます。 つまり、sbyte
, byte
, char
, short
, ushort
の値に対してシフト演算を行う場合、結果はint
となります。 複合代入演算子を使う場合は、自動的に代入先の型にキャストされます。
右オペランド(右項・シフトする量、amount)は、常に左オペランドの型のビット数未満となるようにマスクされます。 例として32ビット整数をシフトしようとする場合、右オペランドの値は31(10)=11111(2)で自動的にマスク(AND演算)されます。 値が32ビット整数でシフト量が33の場合、33(10) AND 31(10) = 1(10)
つまりシフト量1のシフト演算となります。
このため、シフト量が型のビット数を超える値となる場合や、特に逆方向へのシフトを意図して負の値を指定してもそのとおりの動作とはならない点には注意が必要です。
回転シフト・循環シフトを行う場合はBitOperations.RotateLeftメソッド・RotateRightメソッドを使用します。 このメソッドでは、シフト量に負の値を指定すると逆方向への回転シフトとなります。