ビット演算とは
ビット演算とは、その名の通りビット単位での演算を行うことです。
使い道
機械的に比較的軽量な演算を行うので、コードの軽量化に繋がります。
マスキング処理などにも使用することができます。
また、ビットを使用したフラグ管理(ビットフラグ)は軽いフラグの記述の実現が可能となります。
論理積(AND)演算
AND演算とは、二項の各桁の両方が1なら1、そうでないなら0に変換する演算です。
AND演算では&
演算子を使用します。
#include <iostream>
int main() {
int a = 12;
int b = 10;
int result = a & b;
printf_s("result:%d\n", result);
system("pause");
return 0;
}
result:8
12と10を二進数にして考えてみます。
12...1100
10...1010
各桁にAND演算を行うと
0100
となり10進数に直すと8
となります。
論理和(OR)演算
OR演算とは、二項の各桁の片方が1なら1、両方が0なら0に変換する演算です。
OR演算では|
演算子を使用します。
#include <iostream>
int main() {
int a = 12;
int b = 10;
int result = a | b;
printf_s("result:%d\n", result);
system("pause");
return 0;
}
result:14
12と10を二進数にして考えてみます。
12...1100
10...1010
各桁にOR演算を行うと
1110
となり10進数に直すと14
となります。
排他的論理和(XOR)演算
XOR演算とは、片方が1で片方が0のものは1、両方が同じなら0となる演算です。
XOR演算では^
演算子を使用します。
#include <iostream>
int main() {
int a = 12;
int b = 10;
int result = a ^ b;
printf_s("result:%d\n", result);
system("pause");
return 0;
}
result:6
12と10を二進数にして考えてみます。
12...1100
10...1010
各桁にXOR演算を行うと
0110
となり10進数に直すと6
となります。
論理否定(NOT)演算
論理否定は、すべてのビットを反転させる操作のことを指します。
論理否定では~
演算子を使用します。
unsigned intでresultの値を考えると、大きすぎる値になるため、コードは割愛します。
ビットシフト
ビットシフトとは、整数型のビットをずらす操作のことをいいます。
左にビットシフト
左ビットシフトでは<<
演算子を使用し、右オペランドにずらす数を指定します。
#include <iostream>
int main() {
int a = 3;
int left = a << 2;
printf_s("left %d\n", left);
system("pause");
return 0;
}
left:12
二進数にして考えてみます。
3...0011
これを2つ左にずらすため1100
となり、10進数にすると12
となります。
なお、ずらしたために右から出てくる値は0となります。
左にビットシフトを行う操作は2^右オペランド
を左オペランドに乗算したものと同じ結果になります。
右にビットシフト
右ビットシフトでは>>
演算子を使用し、右オペランドにずらす数を指定します。
#include <iostream>
int main() {
int a = 3;
int right = a >> 1;
printf_s("right %d\n", right);
system("pause");
return 0;
}
right:1
二進数にして考えてみます。
3...0011
これを1つ右にずらすため0001
となり、10進数にすると1
となります。
右シフトの場合はコンパイラによっては左端が1で埋められる場合もあります。
右にビットシフトを行う操作は2^右オペランド
を左オペランドに除算したものと同じ結果になります。
総括
ビットフラグを扱う際に必要となる考え方なので、まずは基本をマスターしてみましょう。