Целочисленные битовые операторы
Поможем в ✍️ написании учебной работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

Для целых числовых типов данных - long, int, short, char и byte, определен дополнительный набор операторов, с помощью которых можно проверять и модифицировать состояние отдельных битов соответствующих значений. В таблице 10 приведена сводка таких операторов. Операторы битовой арифметики работают с каждым битом как с самостоятельной величиной.

Таблица 10 – Битовые операторы

Оператор Результат Оператор Результат
~ Побитовое унарное отрицание (NOT)    
& Побитовое И (AND) &= Побитовое И (AND) с присваиванием
| Побитовое ИЛИ (OR) |= Побитовое ИЛИ (OR) с присваиванием
^ Побитовое исключающее ИЛИ (XOR) ^= Побитовое исключающее ИЛИ (XOR) с присваиванием
>> Сдвиг вправо >> = Сдвиг вправо с присваиванием
>>> Сдвиг вправо с заполнением нулями >>>= Сдвиг вправо с заполнением нулями с присваиванием
<< сдвиг влево <<= Сдвиг влево с присваиванием

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

Таблица 11

А В OR AND XOR NOT A
0 0 0 0 0 1
1 0 1 0 1 0
0 1 1 0 1 1
1 1 1 1 0 0

class Bitlogic {

public static void main(String[] args) {

      String binary[] = { "OOOO", "0001", "0010",

                       "0011", "0100", "0101",

                       "0110", "0111", "1000",

                       "1001", "1010", "1011",

                       "1100", "1101", "1110",

                       "1111" };

       int a = 3; // 0+2+1 или двоичное 0011

       int b = 6; // 4+2+0 или двоичное 0110

       int c = a | b;

       int d = a & b;

       int e = a ^ b;

      int f = (~a & b) | (a & ~b);

      int g = ~a & 0x0f;

      System.out.println(" a = " + binary[a]);

      System.out.println(" b = " + binary[b]);

      System.out.println("a | b = " + binary[c]);

      System.out.println("a & b = " + binary[d]);

      System.out.println("a ^ b = " + binary[e]);

       System.out. println("~a & b | а & ~b = " + binary[f]);

      System.out.println("~a = " + binary[g]);

}

}

Ниже приведен результат, полученный при выполнении этой программы:

a = 0011

b = 0110

a | b = 0111

a & b = 0010

a ^  b = 0101

~a & b | a & ~b = 0101

~а = 1100

Сдвиги влево и вправо

Оператор << выполняет сдвиг влево всех битов своего левого операнда на число позиций, заданное правым операндом. При этом часть битов в левых разрядах выходит за границы и теряется, а соответствующие правые позиции заполняются нулями. Ранее уже говорилось об автоматическом повышении типа всего выражения до int в том случае, если в выражении присутствуют операнды типа int или целых типов меньшего размера. Если же хотя бы один из операндов в выражении имеет тип long, то и тип всего выражения повышается до long.

Оператор >> означает в языке Java сдвиг вправо. Он перемещает все биты своего левого операнда вправо на число позиций, заданное правым операндом. Когда биты левого операнда выдвигаются за самую правую позицию слова, они теряются. При сдвиге вправо освобождающиеся старшие (левые) разряды сдвигаемого числа заполняются предыдущим содержимым знакового разряда. Такое поведение называют расширением знакового разряда.

В следующей программе байтовое значение преобразуется в строку, содержащую его шестнадцатеричное представление. Обратите внимание - сдвинутое значение приходится маскировать, то есть логически умножать на значение 0х0f, для того, чтобы очистить заполняемые в результате расширения знака биты и понизить значение до пределов, допустимых при индексировании массива шестнадцатеричных цифр.

class HexByte {

static public void main(String[] args) {

     char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

     byte b = (byte) 0xf1;

     System.out.println("b = 0x" + hex[(b >> 4) & 0x0f] + hex[b & 0x0f]);

}

}

Ниже приведен результат работы этой программы:

b = 0xf1

Беззнаковый сдвиг вправо

Часто требуется, чтобы при сдвиге вправо расширение знакового разряда не происходило, а освобождающиеся левые разряды просто заполнялись бы нулями.

class ByteUShift {

static public void main(String[] args) {

     char hex[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' а ', 'b', ' с ', 'd', 'e','f'};

     byte b = (byte) 0xf1;

     byte c = (byte) (b >> 4);

     byte d = (byte) (b >> 4);

     byte e = (byte) ((b & 0xff) >> 4);

    System.out.println(" b = 0x" + hex[(b >> 4) & 0x0f] + hex[b & 0x0f]);

    System.out.println(" b >> 4 =  0x" + hex[(c >> 4) & 0x0f] +

                       hex[c & 0x0f]);

    System.out.println("b >>> 4 = 0x" + hex[(d >> 4) & 0x0f] +

                       hex[d & 0x0f]);

    System.out.println("(b & 0xff) >> 4 = 0x" + hex[(e >> 4) & 0x0f] +

                       hex[e & 0x0f]);

}

}

Для этого примера переменную b можно было бы инициализировать произвольным отрицательным числом, мы использовали число с шестнадцатеричным представлением 0xf1. Переменной с присваивается результат знакового сдвига b вправо на 4 разряда. Как и ожидалось, расширение знакового разряда приводит к тому, что 0xf1 превращается в 0xff. Затем в переменную d заносится результат беззнакового сдвига b вправо на 4 разряда. Можно было бы ожидать, что в результате d содержит 0x0f, однако на деле мы снова получаем 0xff. Это - результат расширения знакового разряда, выполненного при автоматическом повышении типа переменной b до int перед операцией сдвига вправо. Наконец, в выражении для переменной е нам удается добиться желаемого результата - значения 0x0f. Для этого нам пришлось перед сдвигом вправо логически умножить значение переменной b на маску 0xff, очистив таким образом старшие разряды, заполненные при автоматическом повышении типа. Обратите внимание, что при этом уже нет необходимости использовать беззнаковый сдвиг вправо, поскольку мы знаем состояние знакового бита после операции AND.

b = 0xf1

b >> 4 = 0xff

b >>> 4 = 0xff

b & 0xff) >> 4 = 0x0f

Дата: 2019-02-19, просмотров: 233.