フラグの取得、設定(追加)、解除を行います。
理解しやすくするために0~9の数値に該当するビットを対象に、そして比較しやすいように桁数を4桁に統一し、話を進めます。
2進数対応表 | |
---|---|
10進数 | 2進数 |
0 | 0000 |
1 | 0001 |
2 | 0010 |
3 | 0011 |
4 | 0100 |
5 | 0101 |
6 | 0110 |
7 | 0111 |
8 | 1000 |
9 | 1001 |
ビット演算子 | |
---|---|
演算子 | 説明 |
& | 論理積 |
| | 論理和 |
^ | 排他的論理和 |
~ | 反転 |
ビット演算表
ビット | & | | | ^ | |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 | 1 |
1 | 0 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 |
10進数の「2」を出力してみます。
出力される結果を見やすくするため、2進数はPadLeftを使用し、4桁で揃えています。
int flag = 2; //0010 Console.WriteLine( "10進数 : {0}\n 2進数 : {1}\n\n", flag, Convert.ToString(flag, 2).PadLeft(4, '0') );
Result
10進数 : 2
2進数 : 0010
フラグの取得
フラグが立っているか否かを調べます。フラグを取得する式
x & yビット演算子「&」は"x"と"y"の両方のフラグが立っている場合に1となります。
Example
3 & 2上記の場合、右から二番目の値だけが"1"なのでそれのみを残し、他は"0"となります。
↓
0011 & 0010
↓
結果: 0010
これによってフラグの値のみを抽出できます。
Example
int flag1 = 2;//0010 int flag2 = 3;//0011 Console.WriteLine(flag1 & 2); //2 Console.WriteLine((flag1 & 2) != 0); //True Console.WriteLine(flag2 & 2); //2 Console.WriteLine((flag2 & 2) != 0); //True10進数の「2」、「3」ともに2番目のフラグが立っているのでTrueを返します。
フラグの設定
フラグが立っていない場合、フラグを設定します。フラグを設定する式
x | yビット演算子「|」はどちらか一方、あるいは両方のフラグが立っていれば1となります。
Example
int flag1 = 2;//0010 int flag2 = 3;//0011 int flag3 = 4;//0100 var ret1 = flag1 | flag2; Console.WriteLine(ret1); //3 //2進数に変換します。 Console.WriteLine( Convert.ToString(ret1, 2).PadLeft(4, '0')); //0011 var ret2 = flag2 | flag3; Console.WriteLine(ret2); //7 //2進数に変換します。 Console.WriteLine( Convert.ToString(ret2, 2).PadLeft(4, '0')); //0111 var ret3 = flag3 | flag1; Console.WriteLine(ret3); //6 //2進数に変換します。 Console.WriteLine( Convert.ToString(ret3, 2).PadLeft(4, '0')); //0110
フラグの解除
フラグが立っている場合、フラグを解除します。フラグを解除する式
x & ~y
まず「~」を使用して反転させます。
例えば10進数の「2」を反転させると
「0010」→「1101」(4桁揃え)その後、&演算子を使用し、論理積を求めます。
Example
int flag = 2; int xor = (byte)~flag; Console.WriteLine(xor);//253 //2進数に変換します Console.WriteLine( Convert.ToString(flag, 2).PadLeft(4, '0')); //0010 Console.WriteLine( Convert.ToString(xor, 2).PadLeft(4, '0')); //11111101 //論理積を出力します。 Console.WriteLine(2 & xor); //0 Console.WriteLine(2 & ~2); //0
フラグを使う具体例
もう少し具体的な例を挙げてみます。権限を設定することを想定し、以下のようなenumを作成してみます。
[FlagsAttribute] enum PermissionFlags { None = 0, Read = 1, Create = 1 << 1, Write = 1 << 2, Delete = 1 << 3, All = 1 | 1 << 1 | 1 << 2 | 1 << 3 }
上のPermissionFlagsを使用して権限の取得、追加、削除を行ってみます。
var p = PermissionFlags.Create | PermissionFlags.Read; Console.WriteLine(p); //Read, Create //取得 Console.WriteLine((p & PermissionFlags.Create) != 0); //true //追加 p |= PermissionFlags.Delete; Console.WriteLine(p); //Read, Create, Delete //削除 p &= ~PermissionFlags.Create; Console.WriteLine(p); //Read, Delete
0 Comments:
コメントを投稿