Побитовые операции

Для a = 60 и b = 13:

a = 0011 1100
b = 0000 1101
ОператорРезультатСмысл
a & b12бит 1 только в обоих
a | b61бит 1 хотя бы в одном
a ^ b49биты различаются
~a-61инверсия всех 32 бит int
a << 2240сдвиг влево, нули справа
a >> 215знаковый сдвиг вправо
a >>> 215беззнаковый сдвиг вправо

Разница >> и >>> видна на отрицательных числах: первый заполняет слева знаком, второй — нулями.

Маски

int flags = 0;
int READ = 1 << 0;
int WRITE = 1 << 1;
 
flags |= READ;              // установить
boolean canRead = (flags & READ) != 0; // проверить
flags &= ~READ;             // снять
flags ^= WRITE;             // переключить

Важные правила Java

  • byte, short и char в выражении продвигаются до int;
  • для int используется только 5 младших битов расстояния сдвига: x << 32 равно x << 0;
  • для long — 6 младших битов;
  • x << k похоже на умножение на 2^k, но overflow отбрасывает старшие биты;
  • x & (x - 1) сбрасывает младший установленный бит при x != 0.
static boolean isPowerOfTwo(int x) {
    return x > 0 && (x & (x - 1)) == 0;
}

См. Двоичная система счисления.

На собеседовании

  • & и &&? Побитовая операция против short-circuit boolean.
  • Чем >> отличается от >>>? Знаковым заполнением слева.
  • Почему ~60 == -61? Дополнительный код: ~x == -x - 1.
  • Как проверить степень двойки? x > 0 && (x & (x - 1)) == 0.
  • Тип результата byteA & byteB? int.