Урок 4

Побитовые операции и сдвиги


1. Поразрядные (побитовые) операции

Операция Описание
~ Поразрядная унарная операция НЕ (дополнение)
& Поразрядная логическая операция И (AND, побитовая конъюнкция)
| Поразрядная логическая операция ИЛИ (OR , побитовая дизъюнкция)
^ Поразрядная логическая операция исключающее ИЛИ (XOR)

Побитовые операторы применяются к целочисленными типам long, int, short, char, byte.  Побитовые операторы применяются к каждому отдельному биту каждого операнда.

Результаты выполнения поразрядных логических операций

A

B

A | B

A & B

A ^ B

~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

1.1. Побитовое OR (|)

Результирующий бит, полученный в результате выполнения оператора OR, равен 1, если соответствующий бит в любом из операндов равен 1.
'  00101010   42
 | 00001111   15 
   -------------- 
   00101111   47
'

1.2. Побитовое AND (&)

Значение бита, полученное в результате выполнения побитового оператора AND, &, равно 1, если соответствующие биты в операндах также равны 1. Во всех остальных случаях значение результирующего бита равно 0.
' 00101010   42 
& 00001111   15
  --------------
  00001010   10
'

1.3. Побитовое XOR (^)

Результирующий бит, полученный в результате выполнения оператора XOR, ^, равен 1, если соответствующий бит только в одном из операндов равен 1. Во всех других случаях результирующий бит равен 0.
' 00101010  42 
^ 00001111  15
 --------------
  00100101  37 
'

1.4. Побитовое NOT (~)

Унарный оператор NOT (Не), ~, называемый также побитовым дополнением, инвертирует все биты операнда.
~ 00101010   42
-----------------
  11010101

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

public class Bitwise1 {
    public static void main(String[] args) {
        int a = 3;
        int b = 6;
        int c = a | b;
        int d = a & b;
        int e = a ^ b;
        int f = ~b;
        System.out.println("a = " + Integer.toBinaryString(a));
        System.out.println("b = " + Integer.toBinaryString(b));
        System.out.println("a | b = " + Integer.toBinaryString(c));
        System.out.println("a & b = " + Integer.toBinaryString(d));
        System.out.println("a ^ b = " + Integer.toBinaryString(e));
        System.out.println("~ b = " + Integer.toBinaryString(f));
    }
}

2. Битовые сдвиги

Операция Описание
>> Сдвиг вправо (арифметический сдвиг)
>>> Сдвиг вправо с заполнением нулями (беззнаковый сдвиг)
<< Сдвиг влево
Смещает все двоичные разряды значения на указанное количество позиций.

Общая форма: 

значение << количество
Например:
34<<3, 56>>2, 78>>>1
 
0001<<1 = 0010
0100>>1 = 0010

При сдвиге отрицательных чисел имеется разница в использовании операторов >> и >>>. Операция >> распространяет знаковый (левый) бит направо до конца, >>> заполняет нулями. У положительных чисел результат будет одинаков.

Типы byte и short продвигаются к типу int при вычислении выражения.

Пример битовых сдвигов:

int i = 192;
i       00000000 00000000 00000000 11000000 (192)
i<<1    00000000 00000000 00000001 10000000 (384)
i>>1    00000000 00000000 00000000 01100000 (96)
i>>>1   00000000 00000000 00000000 01100000 (96) 
int i = -192; (двоичная запись в доп. коде)
i       11111111 11111111 11111111 01000000 (-192) 
i<<1    11111111 11111111 11111110 10000000 (-384)
i>>1    11111111 11111111 11111111 10100000 (-96)
i>>>1   01111111 11111111 11111111 10100000 (2147483552)

Пример 2. Побитовый сдвиг влево

public class Bitwise2 {
    public static void main(String[] args) {
        byte a = 64; //0100 0000
        byte b;
        int i = a << 2; // 1 0000 0000
        b = (byte) (a << 2); //0000 0000
        System.out.println("a = " + a);
        System.out.println("i = " + i);
        System.out.println("b = " + b);
    }
}

3. Поразрядные (побитовые) операции с присваиванием

Операция

Описание

&=

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

|=

Поразрядная логическая операция ИЛИ с присваиванием

^=

Поразрядная логическая операция исключающее ИЛИ с присваиванием

>>­

Сдвиг вправо с присваиванием

>>>=

Сдвиг вправо с заполнением нулями и присваиванием

<<=

Сдвиг влево с присваиванием

4. Практическое применение побитовых операций

x & 1 - проверяет чётность числа. Если число четное результат – 0, нечетное -1;
x<<1 – умножение на 2;
x>>1 - деление на два с отбрасыванием любого остатка.
Операция XOR при применения 2 раза к одному и тому же битовому массиву восстанавливает ее исходное значение:

  C = A ^ B

  A = C ^ B 

Пример 3. Использование операции XOR

public class Bitwise3 {
    public static void main(String[] args) {
        int a = 560;
        int maska = 67;
        int b = a ^ maska;
        int c = b ^ maska;
        System.out.println("a = " + a);
        System.out.println("a = " + Integer.toBinaryString(a));
        System.out.println("b = " + b);
        System.out.println("b = " + Integer.toBinaryString(b));
        System.out.println("c = " + c);
        System.out.println("c = " + Integer.toBinaryString(c));
    }
}
Наложение маски - маска позволяет получать значения только определенных битов в последовательности. Например, у нас есть маска 00100100, она позволяет нам получать из последовательности только те биты, которые в ней установлены. В данном случае это 3-й и 7-й разряд. Для этого достаточно выполнить побитовое И с нашей маской и неким числом:
'      001010101 
&      000100100 
    ---------------- 
       000000100
'

 

http://leodestroy.blogspot.com/2013/11/pobitovye-operacii-i-operacii-bitovogo-sdviga-v-Java.html



0 comments
Leave your comment: