JavaRush /Blogue Java /Random-PT /Operadores Lógicos em Java

Operadores Lógicos em Java

Publicado no grupo Random-PT
Operações lógicas em Java.  Operações bit a bit em Java - 1

Operações Lógicas em Java

As operações lógicas são realizadas usando operadores booleanos. Perdoe a tautologia, mas é exatamente assim que as coisas são. Operações lógicas básicas (em programação e matemática) podem ser aplicadas a argumentos lógicos (operandos) e também podem ser usadas para formar expressões mais complexas, semelhantes às operações aritméticas com números. Por exemplo a expressão:

(a | b) | (c < 100) & !(true) ^ (q == 5)
é uma expressão lógica complexa com quatro operandos: (a | b), onde аe bsão variáveis ​​de tipo boolean (c < 100) (true) (q == 5) . Por sua vez, uma expressão lógica simples (a | b)também consiste em dois argumentos de operando. Um operando lógico é uma expressão que pode ser considerada verdadeira ou falsa, verdadeira ou falsa . Na linguagem Java, um operando booleano é uma expressão do tipo booleanou booleano, por exemplo:
  • (2 < 1)— operando lógico, seu valor é falso
  • true- um operando lógico cujo valor é obviamente verdadeiro
  • boolean a- também pode ser um operando lógico, como Boolean a
  • int a = 2- não é um operando lógico , é apenas uma variável do tipoint
  • String a = "true"também não é um operando lógico . Esta é uma string cujo valor de texto é "true".
As seguintes operações lógicas estão disponíveis em Java:
  • Negação lógica , também conhecida NOTcomo inversão. Em Java, é indicado pelo !símbolo “ ” antes do operando. Aplica-se a um operando.
  • Lógico e , também é ANDuma conjunção. Indicado por um símbolo “ &” entre os dois operandos aos quais está aplicado.
  • Lógico ou em Java , também é - OR, também é disjunção. Em Java, é indicado pelo símbolo “ |” entre dois operandos.
  • Disjunção exclusiva ou estrita XOR. Em Java, é indicado pelo símbolo “ ^” entre dois operandos.
  • Em Java, os operadores lógicos incluem o condicional ou , denotado como ||, bem como o condicional e - &&.
Nota: também na lógica matemática consideram a relação de equivalência, ou seja, igualdade. Contudo, em Java, o operador de igualdade==não é considerado um operador lógico. Atenção! Em Java, os operadores lógicos&e|também^se aplicam a números inteiros. Nesse caso, eles funcionam de maneira um pouco diferente e são chamados de operadores lógicos bit a bit (ou bit a bit). Sobre eles - no final do artigo. Vejamos uma tabela com uma breve descrição de cada um dos operadores lógicos Java e, a seguir, iremos descrevê-los com mais detalhes e fornecer exemplos de código.
Operador Java Nome Tipo Pequena descrição Exemplo
! “Não” lógico (negação) Unário !xsignifica “não x”. Retorna verdadeiro se o operando for falso . Retorna false se o operando for true . boolean x = true;
Então
// !x == false
& E lógico ( AND, multiplicação) Binário Retorna verdadeiro se ambos os operandos forem verdadeiros . a = true;
b = false;
Então
a & b == false
| OR lógico ( OR, adição) Binário Retorna verdadeiro se pelo menos um dos operandos for verdadeiro . a = true;
b = false;
Então
a | b == true
^ OU exclusivo lógico ( XOR) Binário Retorna verdadeiro se um e apenas um dos operandos for verdadeiro . Retorna false se ambos os operandos forem true ou false . Essencialmente, retorna verdadeiro se os operandos forem diferentes. a = true;
b = false;
Então
a ^ b == true
&& AND condicional (AND lógico curto) Binário O mesmo que , &mas se o operando à esquerda &for false , este operador retornará false sem verificar o segundo operando.
|| OU condicional (OU lógico curto) Binário O mesmo que , |mas se o operador à esquerda for true , o operador retornará true sem verificar o segundo operando.

Operações lógicas no curso JavaRush

Não há como escapar das operações lógicas, e no curso JavaRush elas aparecem desde os primeiros níveis, junto com as condições e o tipo de dados booleanos. Os programadores aprendem gradualmente a usar os métodos da lógica matemática. Para manipulações mais seguras com construções lógicas, é necessária certa destreza e compreensão de determinados processos. Portanto, essas operações são abordadas com mais detalhes e em um nível completamente diferente no final da missão Multithreading, quando a maioria dos alunos não está mais distraída diretamente pela sintaxe e pelas construções, mas tenta se aprofundar na essência da tarefa.

Operações lógicas em Java.  Operações bit a bit em Java - 2

Operador de negação lógica!

Este operador é unário, o que significa que se aplica a uma única expressão ou operando booleano. É muito simples de entender, como qualquer negação: o operador simplesmente muda o significado da expressão para o seu oposto. Tabela verdade ou resultados da execução de uma operação de negação:
O valor de um !a
falso verdadeiro
verdadeiro falso
Exemplo. Operação de negação lógica
public class Solution {
   public static void main(String[] args) {
       boolean a = true;
       System.out.println(!a); // here our boolean expression reverses its value
       System.out.println(!false); // non-false expression, as you might guess, will be equal to... what?
       System.out.println(!(2 < 5)); // expression (2 < 5) is true, so its negation is false

   }
}
A saída do programa será a seguinte:

false
true
false

AND lógico - &, bem como AND - && condicional

AND lógico ou conjunção é aplicado a duas expressões, e seu resultado será verdadeiro somente se ambos os operandos forem verdadeiros. Ou seja, se um dos operandos aou bfor false , então a expressão a & bserá falsa independente do valor do segundo operador. Se você imaginar que verdadeiro é o número 1 e falso é 0, então o operador &funciona exatamente da mesma forma que a multiplicação regular. Portanto, AND lógico é frequentemente chamado de “multiplicação lógica”. E, aliás, esse fato ajuda a lembrar rapidamente o funcionamento do operador &e não confundi-lo com o operador lógico ou |. Tabela verdade E, também é resultado do trabalho do operador&
a b a&b
verdadeiro verdadeiro verdadeiro
verdadeiro falso falso
falso verdadeiro falso
falso falso falso
E lógico, também é uma conjunção, exemplos:
public class Solution {
   public static void main(String[] args) {
       boolean a = true;
       boolean b = false;
       boolean c = true;
       System.out.println(a & b); // if we multiply true by false, we will definitely get false
       System.out.println(a & c); // true to true will be true
       System.out.println(false & (2 > 5));
 System.out.println((2 < 5) & false);
 // regardless of the truthfulness of the expression in brackets, in which case we have to be content with false
   }
}
Resultado do programa:

false
true
false
false
O operador &&às vezes é chamado de “AND curto”. Produz o mesmo resultado ao trabalhar com operandos lógicos que o operador &. No entanto, há uma diferença em seu trabalho em si. Então, você já percebeu que se a & bo operando da expressão ( ) afor falso , então não faz sentido verificar o valor do operando b: o resultado da operação será definitivamente falso . Portanto, se não precisamos fundamentalmente do valor do segundo operando, utilizando-o &&reduzimos o número de cálculos no programa. Se substituirmos todos os operadores do exemplo &por &&, o resultado será exatamente o mesmo, mas o programa em si será executado um pouco mais rápido (embora não notemos isso, já que estamos falando de mili-micro... em resumo , unidades de tempo muito pequenas).

OR lógico é o operador |, assim como OR condicional é o operador ||

O operador OR em Java é representado pelo símbolo |. Um OR lógico ou disjunção é aplicado a duas expressões e seu resultado será falso se e somente se ambos os operandos forem falsos. Aqui observamos, até certo ponto, a mesma imagem que no caso do operador &, mas exatamente o oposto. Ou seja, se pelo menos um operando for true , então a | bé garantido que a expressão seja verdadeira independentemente do valor do segundo operador. Se &se comportar como uma multiplicação lógica, então OR é uma adição lógica, se você imaginar que verdadeiro é 1 e falso é 0. Lembre-se de que a adição lógica funciona de maneira diferente da adição normal. 1 + 1 neste caso não é igual a 2, mas a 1 (o número 2 simplesmente não existe neste sistema). Às vezes a disjunção é entendida como o máximo de 0 e 1, e neste caso, se pelo menos um operando for igual a 1 ( true ), obtemos exatamente true . Tabela verdade OR, também conhecida como resultado do operador |:
a b uma | b
verdadeiro verdadeiro verdadeiro
verdadeiro falso verdadeiro
falso verdadeiro verdadeiro
falso falso falso
OR lógico, também conhecido como disjunção, exemplo:
public class Solution {
   public static void main(String[] args) {
       boolean a = true;
       boolean b = false;
       boolean c = true;
       System.out.println(!a | b); // Compose the use of two logical operators: a == true, so !a, as we already know, is false.
       System.out.println(a | c);
       System.out.println((2 < 5) | false); // expression (2 < 5) is true, which means that for any second operand we get a true result
       System.out.println((2 > 5) | true);

   }
}
Resultado:

false
true
true
true
Se usarmos o operador condicional OR - ||em vez de |, obteremos exatamente o mesmo resultado, mas, como no caso do condicional AND &&, ele agirá economicamente: se “encontrarmos” o primeiro operando igual a true , o valor de o segundo operando não é verificado, mas imediatamente o resultado é true .

XOR Java - lógico exclusivo OR - operador ^

XOR, adição de módulo 2, XOR lógico, subtração lógica, disjunção estrita, complemento bit a bit... o operador ^tem muitos nomes na álgebra booleana. O resultado da aplicação deste operador a dois operandos será verdadeiro se os operandos forem diferentes e falso se os operandos forem iguais. Portanto, é conveniente compará-lo com a subtração de zeros ( false ) e uns ( true ). Tabela verdade XOR, também conhecida como resultado do operador ^:
Booleano a Booleano b a^b
verdadeiro verdadeiro falso
verdadeiro falso verdadeiro
falso verdadeiro verdadeiro
falso falso falso
Exemplo:
public class Solution {
   public static void main(String[] args) {
       boolean a = true;
       boolean b = false;
       boolean c = true;
       System.out.println(!a ^ b); // Compose the use of two logical operators: a == true, so !a, as we already know, is false.
       System.out.println(a ^ c);
       System.out.println((2 < 5) ^ false);
       System.out.println((2 > 5) ^ true);
   }
}
Resultado:

false
false
true
true

Prioridade de operações lógicas

Assim como na matemática, na programação os operadores possuem uma ordem de execução específica quando aparecem na mesma expressão. Os operadores unários têm vantagens sobre os binários e a multiplicação (mesmo lógica) sobre a adição. Classificamos os operadores lógicos no topo da lista, quanto maior for sua prioridade:
  1. !
  2. &
  3. ^
  4. |
  5. &&
  6. ||
Vejamos exemplos. Conjunção e disjunção ( &e |) têm precedências diferentes:
public class Solution {
   public static void main(String[] args) {
       boolean a = true, b = true, c = false;
       System.out.println(a | b & c);
}
Se tivéssemos trabalhado da esquerda para a direita, ou seja, aplicasse primeiro o operador |e depois - &, teríamos recebido o valor false . Mas, na verdade, se você executar este programa, terá certeza de que a saída será verdadeira , pois o operador lógico AND &terá maior prioridade que o operador lógico OR |. Para evitar confusão, você precisa lembrar o que &se comporta como multiplicação e |o que se comporta como adição. Você pode alterar a ordem de prioridade. Basta usar colchetes, assim como na matemática escolar. Vamos mudar um pouco nosso código de exemplo:
public class Solution {
   public static void main(String[] args) {
       boolean a = true, b = true, c = false;
       System.out.println((a|b)&c);
}
E aí? Primeiro usamos a adição lógica entre colchetes e depois a multiplicação. O resultado será falso .

Expressões lógicas complexas

Claro, podemos combinar expressões e operadores booleanos. Vamos relembrar a expressão do início do artigo:
(a | b) | (c < 100) & !(true) ^ (q == 5)
Agora não parece tão assustador. Vamos escrever um programa que exiba seu valor, tendo previamente determinado os valores de a, b, сe q. Exemplo de cálculo do valor de uma expressão booleana complexa
public class Solution {
   public static void main(String[] args) {
       boolean a = true;
       boolean b = false;
       int c = 25;
       int q = 2;
       System.out.println((a|b) | (c < 100) & !(true)^(q == 5));
   }
}
Observação:qnossa variável é do tipo int, mas q == 5esta é uma expressão booleana, e é igual a false , pois acima inicializamos com qo número 2. O mesmo acontece com a variável c. Este número é igual a 25, mas (c < 100) é uma expressão booleana igual a true . O resultado deste programa:

true
Expressões booleanas complexas podem ser usadas para testar condições muito complexas e ramificadas, mas não devem ser usadas em demasia: elas dificultam a leitura do código.

Operadores bit a bit (bit a bit)

No início do artigo, mencionamos que os operadores &, |e ^podem ser usados ​​em relação aos tipos inteiros Java. Neste caso, eles são operadores bit a bit. Eles também são chamados de bit a bit, pois um dígito é um bit e essas operações funcionam especificamente com bits. É claro que eles funcionam de maneira um pouco diferente dos operadores lógicos e, para entender exatamente como, você precisa saber o que é um sistema numérico binário. Se você não sabe nada sobre isso ou esqueceu completamente, sugerimos que você primeiro leia o artigo Java: bits e bytes e lembre a todos que no sistema numérico binário existem apenas dois dígitos - 0 e 1, e todos os dados no computador é representado precisamente com o uso de zeros e uns condicionais. Qualquer um dos números com os quais estamos acostumados (decimais; para eles existem 10 dígitos diferentes de 0 a 9, com os quais escrevemos quaisquer números) pode ser representado no sistema numérico binário. Você pode converter um número decimal em binário usando a divisão sequencial em uma coluna usando a base do sistema numérico (2). Os restos da divisão em cada etapa, escritos em ordem inversa, nos darão o número binário desejado. Aqui, por exemplo, está a conversão do número decimal 103 em representação binária: Operações lógicas em Java.  Operações bit a bit em Java - 3

Sistema numérico binário no curso JavaRush

No curso JavaRush, eles falam sobre o sistema de numeração binária enquanto estudam a missão MultiThreading (nível 10, aula 1), após a palestra há diversas tarefas para consolidação. No entanto, este tópico não é nada difícil e, mesmo que você ainda não tenha chegado tão longe no curso, provavelmente descobrirá.

Além de &, |e ^Java também usa operadores bit a bit:
  • ~ operador de negação bit a bit
  • >>deslocamento bit a bit para a direita
  • >>>deslocamento à direita bit a bit não assinado
  • <<deslocamento bit a bit para a esquerda
Para iniciantes, os operadores bit a bit parecem muito confusos e artificiais. Na maioria das vezes, eles não entendem para que são necessários, exceto para resolver problemas educacionais. Na verdade, eles podem ser usados, no mínimo, para organizar divisões e multiplicações eficientes, e os profissionais os utilizam para codificação/decodificação, criptografia e geração de números aleatórios.

Operadores bit a bit &, | e ^

Vejamos um exemplo de como esses operadores funcionam. Digamos que temos dois números inteiros:
int a = 25;
int b = 112; 
Precisamos aplicar três operações a eles e &exibir o resultado na tela. Aqui está o código do programa: |^
public class Solution {
   public static void main(String[] args) {

       int a = 25;
       int b = 112;

       int res1 = a & b;
       int res2 = a | b;
       int res3 = a ^ b;

       System.out.println("a & b = " + res1);
       System.out.println("a | b = " + res2);
       System.out.println("a ^ b = " + res3);

   }
}
O resultado do programa é o seguinte:

a & b = 16
a | b = 121
a ^ b = 105
Se você não entende o que está acontecendo, o resultado parece muito, muito misterioso. Na verdade, tudo é mais simples do que parece. Os operadores bit a bit “vêem” os números dos operandos em sua forma binária. E então eles aplicam operadores lógicos &, |ou ^aos dígitos (bits) correspondentes de ambos os números. Assim, para &o último bit da representação binária do número 25 soma-se logicamente ao último bit da representação binária do número 112, o penúltimo bit com o penúltimo, e assim por diante: Operações lógicas em Java.  Operações bit a bit em Java - 4A mesma lógica pode ser rastreada no caso de |e ^. Operações lógicas em Java.  Operações bit a bit em Java - 5

Deslocamento de bit para esquerda ou direita

Existem vários operadores de deslocamento de bits em Java. Os operadores mais comumente usados <<​​são e >>. Eles deslocam a representação binária de um número para a esquerda ou para a direita, respectivamente, e no caso de um deslocamento para a direita, preservando o sinal (explicaremos o que significa preservar o sinal abaixo). Existe outro operador de deslocamento para a direita >>>. Faz a mesma coisa, mas >>não salva o sinal. Então, vamos dar uma olhada no trabalho deles usando um exemplo. int a = 13 a << 1desloca todos os bits da representação binária do número a para a esquerda em 1 bit. Para simplificar, vamos imaginar o número 13 em binário como 0000 1101. Na verdade, esse número se parece com isto: 00000000 00000000 00000000 00001101, já que Java intaloca 4 bytes ou 32 bits para números. No entanto, isso não desempenha um papel no exemplo, portanto, neste exemplo consideraremos nosso número como um byte. Operações lógicas em Java.  Operações bit a bit em Java - 6O bit vago à direita é preenchido com zeros. Como resultado desta operação, obtemos o número 26. a << 2Ele desloca todos os bits da representação binária do número apara a esquerda em 2 bits, e os dois bits vagos à direita são preenchidos com zeros. Como resultado, obteremos o número 52. a << 3O resultado será 104... Notou o padrão? O deslocamento bit a bit apara a esquerda em n posições funciona como multiplicar um número apor 2 elevado à potência de n. O mesmo se aplica aos números negativos. Isso -13 << 3dará o resultado -104. a >> ndesloca a representação binária de um número n posições para a direita. Por exemplo, 13 >> 1 transforma o número 1101 no número 0110, ou seja, 6. E 13 >> 2o resultado será 3. Ou seja, em essência, aqui dividimos o número por 2 elevado à potência de n, onde n é o número de turnos para a direita, mas com uma ressalva: se o número for ímpar, durante esta operação parecemos redefinir o último bit do número. Mas com os negativos a situação é um pouco diferente. Digamos que você tente verificar o que o programa produzirá se você solicitar que ele execute uma operação -13 >> 1. Você verá o número -7, não -6, como você imagina. Isso acontece devido à forma como os números negativos são armazenados em Java e outras linguagens de programação. Eles são armazenados no que é chamado de código complementar. Neste caso, o dígito mais significativo (o da esquerda) é indicado abaixo do sinal. No caso de um número negativo, o dígito mais significativo é 1.

Código adicional

Vamos considerar o número int a = 13. Se no programa você imprimir sua representação binária no console usando o comando System.out.println(Integer.toBinaryString(a));, obteremos 1101. Na verdade, esta é uma notação abreviada, pois o número do tipo intocupa 4 bytes na memória, então o computador o “vê” mais assim:

00000000 00000000 00000000 00001101
O dígito mais significativo é zero, o que significa que temos um número positivo. Para converter em código adicional:
  1. Escrevemos o número -13 no chamado “código direto”. Para fazer isso, altere o dígito mais significativo do número para 1.
    Resultado da ação:

    
    10000000 0000000 0000000 00001101
  2. A seguir, invertemos todos os bits (mudamos 0 para 1 e 1 para 0), exceto o bit de sinal. Na verdade, já mudamos isso.
    Resultado da ação:

    
    11111111 11111111 11111111 11110010

    (sim, as etapas 1 e 2 podem ser combinadas, mas é melhor pensar dessa forma)

  3. Adicione 1 ao número resultante.
    Resultado da ação:

    
    11111111 11111111 11111111 11110011
O número binário resultante é -13, escrito em código de complemento de dois, e o deslocamento de bit (e outras operações) será aplicado especificamente a ele. Só que a diferença na lógica de funcionamento não é perceptível em todas as operações. Digamos que, para o mesmo deslocamento para a esquerda, a diferença seja imperceptível; podemos trabalhar com números negativos da mesma forma que com números positivos. Agora vamos mudar para a direita -13 >> 1. Como nosso operador >>preserva o sinal, nesta operação todos os bits liberados à esquerda são preenchidos não com zeros, mas com uns. Assim, mudando o número

11111111 11111111 11111111 11110011
um bit para a direita, resultando na seguinte sequência de bits:

11111111 11111111 11111111 11111001
Se convertermos esse número em código direto (ou seja, primeiro subtrair 1 e depois inverter todos os bits, exceto o primeiro), obteremos o número:

10000000 00000000 00000000 00000111
ou -7. Agora que entendemos o operador de deslocamento à direita com preservação de sinal, ficará claro como ele difere do operador >>>. a >>> n— esta operação é um deslocamento sem sinal, ou seja, desloca a representação binária de um número apara a direita em n bits, mas preenche os n bits vagos à esquerda não com uns, como o operador >>, mas com zeros. Vamos fazer a operação -13 >>> 1. Já temos o número -13em complemento de dois:

11111111 11111111 11111111 11110011
Deslocando 1 bit para a direita e preenchendo o bit livre com zero, obtemos o seguinte número:

01111111 11111111 11111111 11111001
O que dá o número em notação decimal 2147483641.

Operador de negação bit a bit ~

Este operador unário funciona de forma muito simples: ele inverte cada bit da representação binária de um inteiro. Vamos pegar o número -13:

11111111 11111111 11111111 11110011
A operação de negação bit a bit ~13simplesmente reverterá o valor de cada bit. Como resultado obtemos:

00000000 00000000 00000000 00001100
Ou 12na forma decimal.

Breves conclusões

  • Todos os operadores lógicos se aplicam a expressões booleanas, ou seja, aquelas que podem ser consideradas verdadeiras ou falsas .
  • Если операторы &, | or ^ применяются к числам, речь идёт уже не о логических операциях, а о побитовых. То есть оба числа переводятся в двоичную систему и к этим числам побитово применяют операции логического сложения, умножения or вычитания.
  • В математической логике операторам & и | соответствуют конъюнкция и дизъюнкция.
  • Логическое И похоже на умножения 1 (true) и 0 (false).
  • Логическое ИЛИ напоминает поиск максимума среди 1 (true) и 0 (false).
  • Для побитового отрицания целого числа a используется операция ~a.
  • Для логического отрицания булевского выражения a используется операция !a.
  • Отрицательные числа хранятся и обрабатываются в дополнительном codeе.
  • Поразрядный сдвиг вправо может сохранять знак (>>), а может — не сохранять (>>>).
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION