Сдвиг вправо

Операция сдвига вправо, », сдвигает все биты значения вправо на указанное количество позиций. В общем виде ее можно записать следующим образом:

значение » число

Здесь число указывает количество позиций, на которое нужно сдвинуть вправо биты в значении значение. То есть операция » перемещает все биты в указанном значении вправо на количество позиций, указанное в число.

Следующий фрагмент кода выполняет сдвиг вправо на две позиции в значении 32, в результате чего значение переменной а становится равным 8:

int а = 32;
а = а » 2; // теперь а содержит 8

Когда какие-либо биты в значении "сдвигаются прочь", они теряются. Например, следующий фрагмент кода выполняет сдвиг вправо на две позиции в значении 35, что приводит к утрате двух младших битов и повторной установке значения переменной а равным 8:

int а = 35;
а = а»2; // а по-прежнему содержит 8

Чтобы лучше понять, как выполняется эта операция, рассмотрим ее применение к двоичным представлениям:

00100011 35 » 2 00001000 8

При каждом сдвиге вправо выполняется деление значения на два с отбрасыванием любого остатка. Это свойство можно использовать для выполнения высокопроизводительного целочисленного деления на 2. Конечно, при этом нужно быть уверенным, что никакие биты не будут сдвинуты за пределы правой границы.

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

11111000 -8 »1
11111100 -4

Интересно отметить, что результат сдвига вправо значения -1 всегда равен -1, поскольку дополнительные знаковые разряды добавляют новые единицы к старшим битам.

Иногда при выполнении сдвига вправо появление дополнительных знаковых разрядов нежелательно. Например, следующая программа преобразует значение byte в соответствующее шестнадцатеричное строковое представление. Обратите внимание, что для обеспечения возможности использования значения в качестве индекса массива шестна-дцатеричных символов сдвинутое значение маскируется посредством его объединения со значением OxOf операцией AND, что приводит к отбрасыванию любых битов дополнительных знаковых разрядов.

// Маскирование дополнительных знаковых разрядов.
class HexByte {
static public void main(String args[]) {
char hex[] = ( '0', 4\ '2\ '3', '4', '5', '6\ '7', '8', '9\ 'a', 'b\ 'c\ 'd\ 'e', 'f };
byte b = (byte) Oxfl;
System.out.println ("b = Ox" + hex[(b » 4) & OxOf] + hex [b & OxOf]);
}
}

Вывод этой программы выглядит следующим образом:

b = Oxfl