ビット演算まとめ
私が研究で書くようなコードではあんまり使わないのですが、ある種のたしなみとしてちょっとメモしておきます。>>と<<がどうなるのかよく度忘れするので…
ビット演算とは
読んで字のごとく、ビットを直接操作する演算のことです。足し算よりもほんの少し早く、乗算よりもすごく早いといわれています。また、うまく使うとひとつの変数に複数の役割を持たせるような使い方もできます。いくつかあるフラグをまとめて立てたりおろしたりを1回の演算ですることもできます。
ビット演算の種類
というわけでみていきます。例に載せているのはC#です。
否定演算
ビットを反転させる単項演算です。1を与えれば0、10というビット列を与えれば01がかえってきます。
byte x = 2; //0000 0010(2) byte y = ~x; //1111 1101(2) Console.Write(y); //253
AND演算
ふたつのビット列を見比べて、両方が1の位を1、そうでなければ0を返す二項演算です。&&とは違いますよ?
byte x = 165; //1010 0000(2) byte y = 46; //0010 1110(2) byte z = x & y; //0010 0000(2) Console.Write(z); //32
OR演算
ふたつのビット列を見比べて、どちらかが1の位を1、そうでなければ0を返す二項演算です。こちらも||とは違います。
byte x = 165; //1010 0000(2) byte y = 46; //0010 1110(2) byte z = x | y; //1010 1110(2) Console.Write(z); //174
XOR演算
ふたつのビット列について、どちらかのみ1の位を1、そうでなければ0を返す二項演算です。XOR(Exclusive OR:排他的論理和)はうまく使うと剰余並に便利そうです。
byte x = 165; //1010 0000(2) byte y = 46; //0010 1110(2) byte z = x ^ y; //1000 1110(2) Console.Write(z); //142
シフト演算
これはひとつの変数をビットの配列とみなして、右や左に動かすという演算です。2のn乗倍が高速にできたり、複数のビット列を重ね合わせてひとつのビット列にしたりするときに使うんじゃないでしょうかね?算術シフト*1、論理シフト*2、ローテーションシフト*3など、シフトのされ方によって挙動が異なるので、(私も含め)よくわからない人は符号なし整数で繰り越しや切り捨てが起きて泣かない程度に使っておきましょう。
右シフト
ビット列を右にシフトします。これを符号なし整数型の変数にすると、シフトした分だけ2で割って、余りは切り捨てたことになります。あふれた分は切り捨てられるか、頭のビットに回されるかのどちらかになります。
byte x = 2; //0000 0010(2) byte y = x >> 1; //0000 0001(2) Console.Write(y); //1
左シフト
ビット列を左にシフトします。これを符号なし整数型の変数にすると、シフトした分だけ2をかけたことになります。あふれた分はたいていなかったことになります。
byte x = 2; //0000 0010(2) byte y = x << 1; //0000 0100(2) Console.Write(y); //4
なんで今更これなのか
文字解析しているときに、ある1文字を表すByte型の配列を、ひとつの数値に変換してあれこれしたくなったからです。これは明日のこととも絡んでくるのですが…