Логические операции. Операции отношения. Поразрядные логические операции

Логические операции. Операции отношения. Поразрядные логические операции


Содержание



1. Какие логические операции используются в программах на Java?

В языке Java кроме логических операций, операций отношения и поразрядных логических операций также существуют следующие группы операций:

  • арифметические операции;
  • операции для особых случаев.

Логические операции выполняются только над операндами типа boolean (в отличие от поразрядных логических операций).

Описание логических операций следующее.

Операция   Описание
-----------------------------------
   &       Логическая операция "И"
   |       Логическая операция "ИЛИ"
   ^       Логическая операция исключающее "ИЛИ"
   ||      Сокращенная логическая операция "ИЛИ"
   &&      Сокращенная логическая операция "И"
         Унарная логическая операция "НЕТ"
   &=      Логическая операция "И" с присваиванием
   |=      Логическая операция "ИЛИ" с присваиванием
   =       Логическая операция исключающее "ИЛИ" с присваиванием
   ==      Равно
   !=      Не равно
   ?:      Тернарная логическая операция "если...то...иначе"

2. Какой результат дает применение логических операций !, &, |, ^

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

----------------------------------------
  X      Y     X|Y    X&Y    X^Y    !X
----------------------------------------
false  false  false  false  false  true
true   false  true   false  true   false
false  true   true   false  true   true
true   true   true   true   false  false
----------------------------------------

3. Примеры использования логических операций ~, &, |, ^
// логические операции
boolean b1, b2, b3;

b1 = true;
b2 = false;

b3 = b1 & b2; // b3 = false
b3 = !b1;     // b3 = false
b3 = b1 | b2; // b3 = true
b3 = b1 ^ b2; // b3 = true

4. Какие преимущества дает использование сокращенных логических операций && и ||

Сокращенные логические операции && и || позволяют сократить время вычисления длинных логических выражений.

При использовании операции &&, если значение первого операнда равно false, то нет надобности вычислять второй операнд, так как результат все равно будет false.

Аналогично, при использовании операции ||, если значение первого равно true, то результат всего логического выражения будет равен true. Значит, нет потребности вычислять второй операнд.

Поскольку, в операциях вычисляется только один (первый) операнд, то повышается эффективность кода.

Сокращенные логические операции можно эффективно использовать в коде. Например, если от значения первого операнда зависит необходимость вычисления второго операнда. В этом случае значение второго операнда не вычисляется.

5. Какие операции отношения используются в Java?

Операции отношения еще называют операциями сравнения.

Операции отношения позволяют сравнивать два операнда между собой.

Результатом операции отношения есть логическое значение (boolean) true или false.

Чаще всего операции отношения используются в управляющих операторах условного перехода if и операторах цикла.

В Java поддерживаются следующие операции отношения:

Операция     Описание
-------------------------------
   ==        Равно
   !=        Не равно
   >         Больше
   <         Меньше
   >=        Больше или равно
   <=        Меньше или равно

6. Примеры использования операций отношения

При сравнении двух значений получается результат типа boolean, который может принимать два значения true (истина) или false (ложь).

Пример 1.

// демонстрация операций отношения
int x, y;
boolean b;

x = 8;
y = -5;

b = x>y; // b = true, операция '>' больше
b = x<(y+3); // b = false, операция '<' меньше
b = x == 3-y; // b = true, операция '==' равно
b = x != 0;  // b = true, операция '!=' не равно
b = x >= 8;  // b = true, операция '>=' больше или равно
b = x+y <= 2; // b = false, операция '<=' меньше или равно

Пример 2. Фрагмент решения квадратного уравнения, в котором показано использование операций отношения в операторе условного перехода if.

// фрагмент решения квадратного уравнения
int a, b, c;
double d, x1, x2;

// ввод значений a, b, c
// ...

d = b*b - 4*a*c;

if (d>=0)
{
    if (a!=0)
    {
        x1 = (-b - Math.sqrt(d))/(2*a);
        x2 = (-b + Math.sqrt(d))/(2*a);
        System.out.println("x1 = " + x1);
        System.out.println("x2 = " + x2);
    }
    else
    {
        x1 = x2 = (double)-c / (double)b;
        System.out.println("x1 = x2 = " + x1);
    }
}
else
{
    System.out.println("Уравнение не имеет решения");
}

7. Какие особенности применения поразрядных логических операций в Java?

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

В Java поддерживаются следующие поразрядные логические операции:

Операция      Описание
-----------------------------------------------------
   ~          Поразрядная унарная операция "НЕТ"
            Поразрядная логическая операция "И"
            Поразрядная логическая операция "ИЛИ"
   ^          Поразрядная логическая операция исключающее "ИЛИ"
   >>         Сдвиг вправо
   >>>        Сдвиг вправо с заполнением нулями
   <<         Сдвиг влево
   &=         Поразрядное логическое "И" с присваиванием
   |=         Поразрядное логическое "ИЛИ" с присваиванием
   =           Поразрядное логическое исключающее"ИЛИ" с присваиванием
   >>=        Сдвиг вправо с присваиванием
   >>>=      Сдвиг вправо с заполнением нулями и присваиванием
   <<=        Сдвиг влево с присваиванием
-----------------------------------------------------

8. Какой результат дает применение поразрядных логических операций ~, &, |, ^

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

--------------------------------------
  X    Y    X|Y    X&Y    X^Y    ~X
--------------------------------------
  0    0     0      0      0      1
  1    0     1      0      1      0
  0    1     1      0      1      1
  1    1     1      1      0      0
--------------------------------------

9. Использование поразрядной логической операции ~ (НЕТ). Пример

Поразрядная логическая операция ~ есть унарной. При ее использовании все двоичные разряды инвертируются.

Пример.

int a, b;

a = 65;
b = ~a; // b = -66

a = -66;
b = ~a; // b = 65

10. Использование поразрядной логической операции & (И). Пример

Логическое «И» еще известно как логическое умножение.

Таблица результатов для двух битовых значений имеет вид:

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

В соответствии с этой таблицей происходит побитовое логическое «И» над операндами целых чисел.

Например. Для двух чисел 25 и 18 побитовое «И» даст следующий результат

00011001    = 25
00010010    = 18
----------------
00010000    = 16

Пример применения побитового «И» в программе на Java:

// побитовое логическое "И"
byte a, b, c;

a = 25;
b = 18;
c = (byte)(a & b);  // c = 16

a = -20;
b = 10;
c = (byte)(a & b); // c = 8

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

Операция поразрядного логического «ИЛИ» есть бинарной (требует двух операндов).

Поразрядное логическое «ИЛИ» обозначается |. Логическое «ИЛИ» еще называется логическим сложением.

При выполнении данной операции формируется значение, которое есть результатом побитового логического «ИЛИ» соответствующих разрядов каждого операнда.

Операция ‘ | ‘ для двух двоичных разрядов дает результат:

0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1

Например. Для чисел 25 и 18 побитовое «ИЛИ» дает следующий результат

00011001    = 25
00010010    = 18
----------------
00011011    = 27

Пример применения побитового исключающего «ИЛИ«:

// побитовое логическое "ИЛИ"
byte a, b, c;

a = 25;
b = 18;
c = (byte)(a | b);  // c = 27

a = -20;
b = 10;
c = (byte)(a | b);  // c = -18

12. Использование побитового исключающего «ИЛИ«

Операция побитового исключающего «ИЛИ» есть бинарной (требует двух операндов).

В Java побитовое исключающее «ИЛИ» обозначается символом ^.

Операция ^ для двух разрядов дает результат соответственно таблице:

0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 0

Для операндов 25 и 18 исключающее «ИЛИ» дает следующий результат

00011001    = 25
00010010    = 18
----------------
00001011    = 11

Пример применения побитового «ИЛИ«:

// побитовое исключающее "ИЛИ"
byte a, b, c;

a = 25;
b = 18;
c = (byte)(a ^ b);  // c = 11

a = -20;
b = 10;
c = (byte)(a ^ b);  // c = -26

13. Как представляются отрицательные целочисленные значения?

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

Отрицательные числа представлены в дополнительном коде.

Алгоритм образования отрицательного числа из положительного следующий:

  • все двоичные разряды инвертируются (0 изменяется на 1 и наоборот);
  • к полученному значению добавляется 1.

Пример 1. Представление числа -8 из положительного числа 8. Числа имеют тип byte. Как известно, значение типа byte имеет 8 разрядов (бит).

Положительное число 8   => 00001000
Инвертирование          => 11110111
+ 1                     => 11111000 => -8

Пример 2. Представление числа 8 из отрицательного числа -8.

Отрицательное число -8 => 11111000
Инвертирование         => 00000111
+ 1                    => 00001000 => 8

Если сделать проверку: 8 + (-8) = 0.

          00001000 =>  8
        + 11111000 => -8
-----------------------------
Сумма =>  00000000 =>  0

14. Особенности использования операции сдвига влево (<<)

Операция сдвига влево сдвигает все двоичные разряды влево на заданное число позиций. Общая форма операции сдвига влево:

значение << количество;

где количество – это количество позиций, на которые нужно сдвинуть разряды на величину значение.

При сдвиге влево, самый старший двоичный разряд смещается за границы допустимого диапазона значений и теряется. Из правой стороны добавляется ноль.

Сдвиг влево на n позиций означает умножение числа на 2 в степени n.

Если сдвигаются значения типов byte и short, то сначала они автоматически приводятся к типу int. Поэтому, сдвинутые влево разряды не теряются в границах разрядности типа int (тип int имеет больший размер чем типы byte и short).

Кроме того, при приведении к типу int отрицательное значение типов byte и short сохраняется (сохраняется старший разряд).

Надо быть осторожным при сдвиге значений типов byte и short.

Пример.

Сдвиг числа 27 влево на 1 разряд имеет вид:

00011011 = 27
<<         1
------------
00110110 = 54 = 27*2¹

Сдвиг числа 11 на 3 разряда влево:

00001011 = 11
<<         3
------------
01011000 = 88 = 11*2²

15. Особенности использования операции сдвига вправо (>>)

Операция сдвига вправо сдвигает все двоичные разряды вправо на заданное число позиций. Общий вид операции сдвига вправо:

значение >> количество;

где

количество – это количество позиций, на которые нужно сдвинуть вправо разряды величины значение.

При сдвиге вправо на одну позицию, самый младший двоичный разряд сдвигается вправо и теряется.

Старший разряд (если число положительное) дополняется нулем.

Если число отрицательное, то старший разряд дополняется единицей. Это называется расширением знака.

Сдвиг вправо на n позиций означает деление числа на 2 в степени n.

Пример. Сдвиг вправо числа 27 на 2 разряда:

00011011 = 27
>>         1
------------
00000110 =  6 = 27/2²

Сдвиг вправо на 1 разряд числа 100:

01100100 = 100
>>         1
------------
00110010 =  50 = 100/2¹

Пример сдвига вправо отрицательного числа. Знак числа (старший разряд) сохраняется.

11111000 = -8
>>          1
-------------
11111100 = -4

16. Пример использования операций сдвига влево и сдвига вправо
// сдвиг влево
byte a, b;

a = 27;
b = (byte)(a << 1); // b = 54

a = 18;
b = (byte)(a<<2);   // b = 72

// сдвиг вправо
a = 15;
b = (byte)(a >> 2); // b = 3

a = 88;
b = (byte)(a>>2);   // b = 22

17. Какие особенности применения операции сдвига вправо с заполнением нулями (>>>)

В предшествующих пунктах было определено, что при сдвиге вправо (>>), знак числа сохраняется. То есть, если число отрицательное, то старший разряд дополняется единицей.

Иногда нужно, чтобы при сдвиге вправо знак числа не расширялся. То есть, нужно выполнить беззнаковый сдвиг. Для этого в Java предусмотрена операция сдвига вправо с заполнением нулями, которая обозначается >>>. Эту операцию еще называют беззнаковый сдвиг вправо.

Пример.

// сдвиг вправо с сохранением знака
int a, b;

a = -5;
b = a >> 2; // b=-2 - знак сохраняется

// сдвиг вправо с заполнением нулями
b = a >>> 2; // b=1073741822 - знак теряется

18. Как в Java применяются составные операции сдвига с присваиванием? Пример

В Java поддерживаются следующие операции сдвига с присваиванием:

Операция    Описание
-------------------------------------------------------------
   &=       Поразрядное логическое "И" с присваиванием
   |=       Поразрядное логическое "ИЛИ" с присваиванием
   =        Поразрядное логическое исключающее "ИЛИ" с присваиванием
   >>=      Сдвиг вправо с присваиванием
   >>>=     Сдвиг вправо с заполнением нулями и присваиванием
   <<=      Сдвиг влево с присваиванием

Эти операции аналогичны операциям:

&   – логическое побитовое "И"
|   – логическое побитовое "ИЛИ"
^   – логическое побитовое исключающее "ИЛИ"
>>  – побитовый сдвиг вправо
<<  – побитовый сдвиг влево
>>> – побитовый сдвиг вправо с заполнением нулями

Пример.

// поразрядные составные операции с присваиванием
int a, b, c;

a = 15;
b = 22;
b &= a; // b = b & a, b = 6

b = 22;
b |= a; // b = b | a, b = 31

b = 22;
b ^= a; // b = b ^ a, b = 25

b = -22;
b >>= 1; // b = b >> 1; b = -11

b = -22;
b <<= 1; // b = b << 1; b = -44

b = -22;
b >>>= 1; // b = 2147483637


Связанные темы