Да, иногда переводят в двоичный вид, это несложно.
Но иногда это не нужно. Например, если у нас битовая операция ИЛИ, то мы понимаем, что нашей переменной устанавливается какой-то флаг. Например,
State = State | FLYING | AGGRESSIVE
Даст нам понимание, что этому State присвоены два флага Flying и Aggressive.
Далее, в коде, если мы захотим узнать, есть ли у объекта признак Flying, то мы напишем
IsFlying = State & FLYING
Если 0, то будет False, иначе True.
Тут есть замечание. Обычно флаги делают в виде одного единственного бита 1 на всей двоичной последовательности. То есть, это будут числа степени двойки: 1,2,4,8,16,32,64,128,512,1024,2048,...
Но это не обязательно так.
Прикол побитовых операций в том, что ими удобно оперировать, если пользоваться ими как флагами.
Смотри, мы в одном байтовом числе можем хранить 8 флагов, состояний.
То есть, вместо записи:
0) IsEnemy = true
1) WaterType = false
2) Aggressive = false
3) CanFly = true
4) HasEyes = true
5) HasFire = true
6) IsDead = false
7) IsVehicle = false
мы можем упаковать эти признаки (состояния) в число 0x00111001 => 32+16+8+1 = 57
То есть, число 57 говорит нам, что некий объект является врагом, он ещё живой, может летать, у него глаза, дышит огнём.
Слов много, я число короткое. MY_OBJ = 57
Теперь, скажем, у нас есть маска, определяющая, является ли объект летающим врагом - 0x00001001 => 9
FLYING_ENEMY = 9
Теперь мы можем сравнить наш объект:
if (MY_OBJ & FLYING_ENEMY) then {
//устанавливаем, например, флаг, что он умер
DEAD_FLAG = 0x01000000; // 64
MY_OBJ = MY_OBJ | DEAD_FLAG; => 0x01111001 = 64+57 = 121
}