Побитовые операции в Java - Вопросы

Всего: 6 вопросов

1. 

Чем отличается оператор >> от >>>?

>> — арифметический сдвиг вправо: слева копируется знаковый бит, поэтому знак числа сохраняется (у отрицательных дописываются единицы). >>> — беззнаковый (логический) сдвиг: слева всегда дописываются нули, из-за чего отрицательное число превращается в большое положительное. Для неотрицательных чисел оба оператора дают одинаковый результат. Оператора <<< в Java нет. Пример: -8 >> 1 равно -4, а -8 >>> 1 равно 2147483644.

2. 

Почему ~x всегда равно -x - 1?

Целые числа в Java хранятся в дополнительном коде (two's complement). Оператор ~ инвертирует все биты. В дополнительном коде смена знака выполняется как «инверсия битов плюс единица»: -x = ~x + 1. Отсюда напрямую следует ~x = -x - 1. Например: ~5 = -6, ~0 = -1, ~(-1) = 0.

3. 

Что такое побитовая маска и как она работает с оператором &?

Маска — это число, в котором единичные биты отмечают интересующие позиции. Выражение value & mask обнуляет все биты значения, кроме тех, что стоят под единицами маски, — так извлекают отдельные биты или проверяют флаги. Например, value & 0xFF оставляет только младший байт, а flags & READ_FLAG показывает, установлен ли конкретный флаг (результат ненулевой — установлен), где READ_FLAG — константа-флаг, например static final int READ_FLAG = 0x01;. Переменную с маской принято называть mask.

4. 

Как проверить чётность числа без оператора %?

Использовать x & 1. Младший бит равен 1 у нечётных чисел и 0 у чётных, поэтому (x & 1) == 0 означает чётное число, а (x & 1) == 1 — нечётное. Приём корректно работает и для отрицательных чисел (в отличие от x % 2, который для отрицательных может вернуть -1) и обычно выполняется быстрее деления.

5. 

Что происходит с типами byte и short при побитовых операциях?

Перед вычислением операнды типов byte и short автоматически расширяются (promotion) до int. Поэтому результат операций &, |, ^ и сдвигов имеет тип int, и присвоить его обратно в byte/short без явного приведения нельзя. Например, byte b = 10; int r = b << 28; — результат автоматически становится типом int и даёт значение, которое в byte уже не помещается.

6. 

Как умножение и деление на степень двойки выражаются через сдвиги?

Сдвиг влево на n бит умножает число на 2 в степени n: x << 1 — это x*2, x << 3 — это x*8. Сдвиг вправо >> на n бит делит на 2 в степени n с округлением вниз: x >> 1 — это x/2. Важные нюансы: при << возможно переполнение (старшие биты уходят за пределы int), а для отрицательных чисел >> округляет в сторону минус бесконечности, а не к нулю, как обычное деление /.

Страница 1 из 1