Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
49
Добавлен:
12.05.2015
Размер:
1.82 Mб
Скачать

Глава 4. Операции 93_

указанное в пшп. Для каждого сдвига влево, старший бит выходит за пределы поля значения (и теряется), а справа вводится нуль. Это означает, что, когда левый сдвиг применяется к int-операнду, биты теряются сразу же, как толь­ко они сдвигаются за 31-ю разрядную позицию. Если операнд — long, то биты выше 63-й разрядной позиции теряются.

Когда вы сдвигаете byte- и short-значения, автоматическое расширение ти­па в Java дает неожиданные результаты. Как вы знаете, значения byte и short раширяются до int во время вычисления (оценки) выражения. Кроме того, результат вычисления такого выражения также имеет тип int. Это означает, что результат левого сдвига на byte- или short-значении будет int и биты, сдвинутые влево, не будут потеряны, пока они не сдвинутся за по­следнюю 31-ю разрядную позицию. Кроме того, отрицательное byte- или short-значение при расширении до int будет расширено своей знаковой позицией, т. е. его старшие биты будут заполнены единицами. Выполнение левого сдвига в значениях до byte или short подразумевает, что следует от­бросить старшие байты int-результата. Например, если сдвигается влево byte-значение, то оно будет сначала расширено до int и затем сдвинуто. Далее, если нужно сохранить byte-тип результата, следует отбросить три верхних байта результата. Проще всего это выполняется с помощью явного приведения типа результата обратно в byte. Эту концепцию демонстрирует следующая программа:

// Левый сдвиг byte-значения, class ByteShift {

public static void main(String args [ ]) {

byte a = 64, b;

int i ;

i = a « 2;

b = (byte) (a « 2) ; // явное приведение типа в byte

System.out.println("Исходное значение а: " + a); System.out.println("i и b: " + i + " " + b); } ) '

Вывод, сгенерированный этой программой: !

Исходное значение а: 64 i и Ь: 256 О

Так как переменная а расширяется до int с целью вычислений, двойной левый сдвиг значения 64 (0100 0000) приводит к тому, что переменная i со­держит значение 256 (1 0000 0000). Однако значение в переменной ь содер­жит 0, потому что после сдвига младший байт становится нулевым, а его единственный единичный бит был выдвинут из поля хранения bite-значения.

94 Часть I. Язык Java

Так как каждый левый сдвиг имеет эффект удвоения первоначального зна­чения, программисты часто используют этот факт как эффективную альтер­нативу умножению на 2. Но следует соблюдать осторожность: если вы сдви­нете бит со значением 1 в самую старшую позицию (бит 31 или 63), то зна­чение станет отрицательным. Следующая программа иллюстрирует это положение:

// Левый сдвиг, как быстрый способ умножения на 2. class MultByTwo {

public static void main(String args [ ]) {

int i ;

int num = OxFFFFFFE;

for(i=0; i<4; i++) { num = num « 1; System.out.println(num); } } }

Программа генерирует следующий вывод:

536870908 1073741816 2147483632 -32

Начальное значение было выбрано так, чтобы после смещения влево на 4 позиции был получен результат -32. Видно, когда единичный бит сдви­нулся в позицию 31, число стало интерпретироваться как отрицательное.

Правый сдвиг

Операция правого сдвига (») сдвигает все биты значения вправо на указан­ное количество разрядов. Ее общая форма:

value » пшп

Здесь num определяет число позиций правого сдвига в значении value. To есть » передвигает все биты в указанном значении вправо на число разряд­ных позиций, указанных в num.

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

int a = 32;

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

Соседние файлы в папке JavaLit