C#、およびVB(7.1以降)では、言語組み込みのシフト演算として、以下のシフト演算子が用意されています。 代入先を左オペランド(左項)とする複合代入演算子も用意されています。
シフト演算 | 演算子 | |
---|---|---|
C# | VB(7.1以降) | |
左シフト |
<< , <<= |
<< , <<= |
右シフト |
>> , >>= |
>> , >>= |
右シフト演算子は、左オペランド(左項・シフトされる値)が符号付き整数の場合は算術シフト(負数の場合は上位側ビットに1
、正数の場合は0
が補われる)となり、符号無し整数の場合は論理シフト(上位側ビットに常に0
が補われる)となります。 言い換えると、右シフト演算子では常に最上位ビット(符号ビット)と同じ値が補われます。 左シフト演算子では、常に0
が補われます。
VBにおけるシフト演算子は、Char
を除く各整数型に対して使用できます。 シフト演算の結果は、常に左オペランド(シフトされる値)と同じ型となります。
右シフト・左シフト演算子を使ってシフト演算を行う
Imports System
Module Sample
Sub Main()
Dim x As Integer = 1 ' 32ビット整数
Console.WriteLine(x.ToBinary())
' 左に1ビットシフトする
x = x << 1
Console.WriteLine(x.ToBinary())
' 複合代入演算子、動作は上と同じ
x <<= 1
Console.WriteLine(x.ToBinary())
x = Integer.MinValue
Console.WriteLine(x.ToBinary())
' 右に1ビットシフトする
x = x >> 1
Console.WriteLine(x.ToBinary())
x >>= 1 ' 複合代入演算子、動作は上と同じ
Console.WriteLine(x.ToBinary())
End Sub
#Region "数値を二進数表記の文字列化するためのメソッド"
<System.Runtime.CompilerServices.Extension> _
Function ToBinary(ByVal number As Integer) As String
Return "&B_" + Convert.ToString(number, 2).PadLeft(8 * Len(number), "0"c)
End Function
#End Region
End Module
実行結果
&B_00000000000000000000000000000001 &B_00000000000000000000000000000010 &B_00000000000000000000000000000100 &B_10000000000000000000000000000000 &B_11000000000000000000000000000000 &B_11100000000000000000000000000000
右オペランド(右項・シフトする量、amount)は、常に左オペランドの型のビット数未満となるようにマスクされます。 例として32ビット整数をシフトしようとする場合、右オペランドの値は31(10)=11111(2)で自動的にマスク(AND演算)されます。 値が32ビット整数でシフト量が33の場合、33(10) AND 31(10) = 1(10)
つまりシフト量1のシフト演算となります。
このため、シフト量が型のビット数を超える値となる場合や、特に逆方向へのシフトを意図して負の値を指定してもそのとおりの動作とはならない点には注意が必要です。
回転シフト・循環シフトを行う場合はBitOperations.RotateLeftメソッド・RotateRightメソッドを使用します。 このメソッドでは、シフト量に負の値を指定すると逆方向への回転シフトとなります。