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

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

Так как поразрядные операции манипулируют битами в пределах целого числа, важно понять, каково воздействие таких манипуляций на его значе­ние. В частности, полезно знать, как Java хранит целочисленные значения и как он представляет отрицательные числа. Поэтому, прежде чем продол­жить, сделаем краткий обзор этих двух тем.

Все целые типы представляются двоичными числами с разным количеством разрядов. Например, целочисленное значение 42 типа byte в двоичном представлении есть 00101010, где каждая позиция представляется степенью двойки, начиная с 2° в самом правом разряде. Следующая битовая позиция (слева направо) будет представляться как 21 и т. д. (т. е. разряды нумеруются справа от 0). Двоичное представление числа 42 имеет единицы в позициях 5, 3 и 1, так что 42 есть сумма 25 + 23 + 21 или 32 + 8 + 2.

Все целые типы (кроме char) — это целые числа со знаком. Это означает, что они могут представлять как отрицательные значения, так и положитель­ные. Java использует кодирование, известное как дополнение до двух, озна­чающее, что отрицательные числа представляются инвертированием (за­меной 1 на 0 и наоборот) всех битов в (положительном) значении с по­следующим прибавлением 1 к результату. Например, —42 представляется инвертированием всех битов р двоичном представлении числа 42 (т. е. в 00101010), что дает 11010101, затем прибавляется (двоичная) 1, что приво­дит к 11010110 (это и есть двоичное представление —42 в дополнительном коде). Чтобы декодировать отрицательное двоичное представление обратно в десятичную форму, сначала инвертируют все биты, затем преобразуют их в десятичную форму и к ней добавляют 1 (не забыв изменить знак результа­та). Например, инверсия 11010110 дает 00101001 (или десятичное 41), так что, если прибавить 1 и изменить знак, то получим —42.

Причину использования в Java (и большинстве других машинных языков) дополнения до двух достаточно просто проследить, если рассмотреть про­блему перехода нуля. Для типа byte нулевое значение представляется как 00000000. Простое инвертирование всех битов (которое называют дополнени­ем до единицы) дает 11111111, что формально должно создать отрицательный нуль. Неприятность в том, что такой "отрицательный нуль" недопустим в целочисленной математике (мы видим, что с учетом знакового разряда это на самом деле представление —1). Данная проблема решается следующим образом: для представления отрицательных значений используется дополне­ние до двух. Дополнение до двух для 00000000 вычисляется так: после пораз­рядной инверсии этого значения к нему добавляется (двоичная) 1, что дает 100000000. Это приводит к тому, что единичный бит выдвигается слишком далеко влево и выходит за пределы размеров byte-значения (8 бит). Поведе­ние становится правильным, т. к. —О имеет то же двоичное значение, что +0, а 11111111 кодирует —1. Хотя в предшествующем примере мы использо­вали byte-значение, тот же основной принцип применяется ко всем целым типам Java.

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

Из-за того, что Java использует дополнение до двух для хранения отрица­тельных чисел, а также потому, что в Java все целые значения — со знаками, применение поразрядных операций может легко породить неожиданные ре­зультаты. Например, включение старшего бита приведет к тому, что резуль­тирующее значение будет интерпретироваться как отрицательное число, не­зависимо от того, входило ли это в ваши намерения или нет. Чтобы избе­жать неприятных сюрпризов, просто помните, что старший бит определяет знак целого числа независимо от того, как этот старший бит был установлен.

Поразрядные логические операции

Поразрядные логические операции это &, |, - и ~. Табл. 4.3 показывает ре­зультат каждой операции1. При последующем обсуждении имейте в виду, что поразрядные операции применяются к каждому индивидуальному биту в каждом операнде.

Таблица 4.3. Поразрядные логические операции Java

А в А|В А&В АЛВ ~А

0 о о о о.1

1 0 1 о 1 0

0 1 1 ' о 1 , 1 1 ' 1 1 о о

Поразрядное отрицание

Унарная операция поразрядного отрицания (~), называемая также поразряд­ным дополнением, инвертирует все биты своего операнда. Например, число 42, которое представляется следующей комбинацией двоичных разрядов:

00101010

после того как применяется операция унарного отрицания, становится

11010101

Поразрядное И

Операция поразрядного И (&) производит единичный бит, если оба операн­да также единичные. Во всех других случаях получается нулевой бит. На­пример:

' На самом деле это не одна, а несколько таблиц, называемые таблицами истинности. Примеч. ред.

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