JavaRush /Blog Java /Random-ES /Operadores lógicos en Java

Operadores lógicos en Java

Publicado en el grupo Random-ES
Operaciones lógicas en Java.  Operaciones bit a bit en Java - 1

Operaciones lógicas en Java

Las operaciones lógicas se realizan mediante operadores booleanos. Perdón por la tautología, pero así es exactamente como son las cosas. Las operaciones lógicas básicas (en programación y matemáticas) se pueden aplicar a argumentos lógicos (operandos) y también se pueden usar para formar expresiones más complejas, similares a las operaciones aritméticas con números. Por ejemplo la expresión:

(a | b) | (c < 100) & !(true) ^ (q == 5)
es una expresión lógica compleja con cuatro operandos: (a | b), donde аy bson variables de tipo A boolean (c < 100) (true) (q == 5) su vez, una expresión lógica simple (a | b)también consta de dos argumentos de operando. Un operando lógico es una expresión que se puede decir que es verdadera o falsa, verdadera o falsa . En lenguaje Java, un operando booleano es una expresión de tipo booleanbooleano, por ejemplo:
  • (2 < 1)— operando lógico, su valor es falso
  • true- un operando lógico cuyo valor es obviamente verdadero
  • boolean a- también puede ser un operando lógico, como booleano a
  • int a = 2- no es un operando lógico , es sólo una variable de tipoint
  • String a = "true"Tampoco es un operando lógico . Esta es una cadena cuyo valor de texto es "true".
Las siguientes operaciones lógicas están disponibles en Java:
  • Negación lógica , también conocida NOTcomo inversión. En Java, se indica con el !símbolo " " antes del operando. Se aplica a un operando.
  • Lógico y , también es ANDuna conjunción. Indicado por un símbolo “ &” entre los dos operandos a los que se aplica.
  • Lógico o en Java , también es - OR, también es disyunción. En Java, se indica con el símbolo " |" entre dos operandos.
  • Disyunción exclusiva o , XORestricta. En Java, se indica con el símbolo " ^" entre dos operandos.
  • En Java, los operadores lógicos incluyen el condicional o , denotado como ||, así como el condicional y - &&.
Nota: también en lógica matemática consideran la relación de equivalencia, es decir, igualdad. Sin embargo, en Java, el operador de igualdad==no se considera un operador lógico. ¡Atención! En Java, los operadores lógicos&y|se^aplican a números enteros. En este caso, funcionan de forma ligeramente diferente y se denominan operadores lógicos bit a bit (o bit a bit). Sobre ellos, hacia el final del artículo. Veamos una tabla con una breve descripción de cada uno de los operadores lógicos de Java, y a continuación los describiremos con más detalle y proporcionaremos ejemplos de código.
operador java Nombre Tipo Breve descripción Ejemplo
! “No” lógico (negación) unario !xsignifica "no x". Devuelve verdadero si el operando es falso . Devuelve falso si el operando es verdadero . boolean x = true;
Entonces
// !x == false
& AND lógico ( AND, multiplicación) Binario Devuelve verdadero si ambos operandos son verdaderos . a = true;
b = false;
Entonces
a & b == false
| O lógico ( OR, suma) Binario Devuelve verdadero si al menos uno de los operandos es verdadero . a = true;
b = false;
Entonces
a | b == true
^ Exclusivo lógico O ( XOR) Binario Devuelve verdadero si uno y sólo uno de los operandos es verdadero . Devuelve falso si ambos operandos son verdaderos o falsos . Básicamente, devuelve verdadero si los operandos son diferentes. a = true;
b = false;
Entonces
a ^ b == true
&& AND condicional (Y lógico corto) Binario Igual que , &pero si el operando a la izquierda de &es false , este operador devuelve false sin verificar el segundo operando.
|| O condicional (O lógico corto) Binario Igual que, |pero si el operador de la izquierda es verdadero , el operador devuelve verdadero sin verificar el segundo operando.

Operaciones lógicas en el curso JavaRush

No hay escapatoria a las operaciones lógicas, y en el curso de JavaRush aparecen desde los primeros niveles, junto con las condiciones y el tipo de datos booleanos. Los programadores aprenden gradualmente a utilizar los métodos de la lógica matemática. Para manipular con mayor confianza construcciones lógicas, se requiere cierta destreza y comprensión de ciertos procesos. Por lo tanto, estas operaciones se abordan con más detalle y en un nivel completamente diferente al final de la misión Multithreading, cuando la mayoría de los estudiantes ya no se distraen demasiado directamente con la sintaxis y las construcciones, sino que intentan profundizar en la esencia de la tarea.

Operaciones lógicas en Java.  Operaciones bit a bit en Java - 2

Operador de negación lógica!

Este operador es unario, lo que significa que se aplica a una única expresión u operando booleano. Es muy sencillo de entender, como cualquier negación: el operador simplemente cambia el significado de la expresión por su opuesto. Tabla de verdad o resultados de realizar una operación de negación:
El valor de un !a
FALSO verdadero
verdadero FALSO
Ejemplo. Operación de negación lógica
public class Solution {
   public static void main(String[] args) {
       boolean a = true;
       System.out.println(!a); // aquí nuestra expresión booleana invierte su valor
       System.out.println(!false); // la expresión no falsa, como puede suponer, será igual a... ¿qué?
       System.out.println(!(2 < 5)); // la expresión (2 < 5) es verdadera, por lo que su negación es falsa

   }
}
El resultado del programa será el siguiente:

false
true
false

AND lógico - &, así como AND condicional - &&

La conjunción o AND lógica se aplica a dos expresiones y su resultado será verdadero solo si ambos operandos son verdaderos. Es decir, si uno de los operandos ao bes falso , entonces la expresión a & bserá falsa independientemente del valor del segundo operador. Si imaginas que verdadero es el número 1 y falso es 0, entonces el operador &funciona exactamente igual que la multiplicación normal. Por lo tanto, el AND lógico a menudo se denomina "multiplicación lógica". Y, por cierto, este hecho ayuda a recordar rápidamente el funcionamiento del operador &y no confundirlo con el lógico u operador |. Tabla de verdad Y, también es resultado del trabajo del operador.&
a b a&b
verdadero verdadero verdadero
verdadero FALSO FALSO
FALSO verdadero FALSO
FALSO FALSO FALSO
AND lógico, también es conjunción, ejemplos:
public class Solution {
   public static void main(String[] args) {
       boolean a = true;
       boolean b = false;
       boolean c = true;
       System.out.println(a & b); // si multiplicamos verdadero por falso, definitivamente obtendremos falso
       System.out.println(a & c); // verdadero a verdadero será verdadero
       System.out.println(false & (2 > 5));
 System.out.println((2 < 5) & false);
 // independientemente de la veracidad de la expresión entre paréntesis, en cuyo caso tenemos que contentarnos con false
   }
}
Resultado del programa:

false
true
false
false
El operador &&a veces se denomina "Y corto". Produce el mismo resultado cuando se trabaja con operandos lógicos que el operador &. Sin embargo, hay una diferencia en su trabajo en sí. Entonces, ya habrás notado que si a & bel operando en la expresión () aes falso , entonces no tiene sentido verificar el valor del operando b: el resultado de la operación definitivamente será falso . Entonces, si fundamentalmente no necesitamos el valor del segundo operando, al usarlo &&reducimos la cantidad de cálculos en el programa. Si reemplazamos todos los operadores del ejemplo &por &&, el resultado será exactamente el mismo, pero el programa en sí se ejecutará un poco más rápido (aunque no lo notaremos, ya que estamos hablando de mili-micro... en definitiva , unidades de tiempo muy pequeñas).

El OR lógico es el operador |, así como el OR condicional es el operador ||

El operador OR en Java está representado por el símbolo |. Se aplica un OR o disyunción lógica a dos expresiones y su resultado será falso si y sólo si ambos operandos son falsos. Aquí observamos hasta cierto punto la misma imagen que en el caso del operador &, pero exactamente al revés. Es decir, si al menos un operando es verdadero , entonces a | bse garantiza que la expresión será verdadera independientemente del valor del segundo operador. Si &se comporta como una multiplicación lógica, entonces OR es una suma lógica, si imaginas que verdadero es 1 y falso es 0. Solo recuerda que la suma lógica funciona de manera diferente a la suma normal. 1 + 1 en este caso no es igual a 2, sino a 1 (el número 2 simplemente no existe en este sistema). A veces se entiende por disyunción el máximo de 0 y 1, y en este caso, si al menos un operando es igual a 1 ( verdadero ), obtenemos exactamente verdadero . O tabla de verdad, también conocida como resultado del operador |:
a b un | b
verdadero verdadero verdadero
verdadero FALSO verdadero
FALSO verdadero verdadero
FALSO FALSO FALSO
OR lógico, también conocido como disyunción, ejemplo:
public class Solution {
   public static void main(String[] args) {
       boolean a = true;
       boolean b = false;
       boolean c = true;
       System.out.println(!a | b); // Componga el uso de dos operadores lógicos: a == verdadero, entonces !a, como ya sabemos, es falso.
       System.out.println(a | c);
       System.out.println((2 < 5) | false); // expresión (2 < 5) es verdadera, lo que significa que para cualquier segundo operando obtenemos un resultado verdadero
       System.out.println((2 > 5) | true);

   }
}
Resultado:

false
true
true
true
Si utilizamos el operador OR condicional - ||en lugar de |, obtendremos exactamente el mismo resultado, pero, como en el caso del AND condicional &&, actuará de forma económica: si “nos topamos” con el primer operando igual a verdadero , el valor de el segundo operando no se verifica, pero inmediatamente el resultado es verdadero .

XOR Java - O lógico exclusivo - operador ^

XOR, suma de módulo 2, XOR lógico, resta lógica, disyunción estricta, complemento bit a bit... el operador ^tiene muchos nombres en álgebra booleana. El resultado de aplicar este operador a dos operandos será verdadero si los operandos son diferentes y falso si los operandos son iguales. Por tanto, conviene compararlo con la resta de ceros ( falso ) y unos ( verdadero ). Tabla de verdad XOR, también conocida como resultado del operador ^:
booleano a booleano b a^b
verdadero verdadero FALSO
verdadero FALSO verdadero
FALSO verdadero verdadero
FALSO FALSO FALSO
Ejemplo:
public class Solution {
   public static void main(String[] args) {
       boolean a = true;
       boolean b = false;
       boolean c = true;
       System.out.println(!a ^ b); // Componga el uso de dos operadores lógicos: a == verdadero, entonces !a, como ya sabemos, es falso.
       System.out.println(a ^ c);
       System.out.println((2 < 5) ^ false);
       System.out.println((2 > 5) ^ true);
   }
}
Resultado:

false
false
true
true

Prioridad de las operaciones lógicas.

Al igual que en matemáticas, en programación los operadores tienen un orden de ejecución específico cuando aparecen en una misma expresión. Los operadores unarios tienen ventajas sobre los binarios y la multiplicación (incluso lógica) sobre la suma. Hemos clasificado a los operadores lógicos más arriba en la lista, cuanto mayor sea su prioridad:
  1. !
  2. &
  3. ^
  4. |
  5. &&
  6. ||
Veamos ejemplos. La conjunción y la disyunción ( &y |) tienen diferente precedencia:
public class Solution {
   public static void main(String[] args) {
       boolean a = true, b = true, c = false;
       System.out.println(a | b & c);
}
Si procediéramos de izquierda a derecha, es decir, aplicáramos primero el operador |y luego - &, obtendríamos el valor false . Pero, de hecho, si ejecuta este programa, estará seguro de que el resultado será verdadero , ya que el operador lógico AND &tendrá mayor prioridad que el operador lógico OR |. Para evitar confusiones, es necesario recordar qué &se comporta como multiplicación y |qué se comporta como suma. Puede cambiar el orden de prioridad. Simplemente use paréntesis, como en matemáticas escolares. Cambiemos un poco nuestro código de ejemplo:
public class Solution {
   public static void main(String[] args) {
       boolean a = true, b = true, c = false;
       System.out.println((a|b)&c);
}
¿Qué pasa? Primero usamos la suma lógica entre paréntesis y luego la multiplicación. El resultado será falso .

Expresiones lógicas complejas

Por supuesto, podemos combinar expresiones y operadores booleanos. Recordemos la expresión del principio del artículo:
(a | b) | (c < 100) & !(true) ^ (q == 5)
Ahora no parece tan aterrador. Escribamos un programa que muestre su valor, habiendo determinado previamente los valores de a, y . Ejemplo de cálculo del valor de una expresión booleana compleja bсq
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));
   }
}
Nota:qnuestra variable es de tipo int, pero q == 5esta es una expresión booleana, y es igual a false , ya que arriba inicializamos con qel número 2. Lo mismo ocurre con la variable c. Este número es igual a 25, pero (c < 100) es una expresión booleana igual a verdadero . El resultado de este programa:

true
Se pueden usar expresiones booleanas complejas para probar condiciones muy complejas y ramificadas, pero no se deben usar en exceso: dificultan la lectura del código.

Operadores bit a bit (bit a bit)

Al principio del artículo, mencionamos que los operadores &y |se ^pueden usar en relación con los tipos de enteros de Java. En este caso son operadores bit a bit. También se les llama bit a bit, ya que un dígito es un bit, y estas operaciones funcionan específicamente con bits. Por supuesto, funcionan de manera algo diferente a los operadores lógicos y, para entender exactamente cómo, es necesario saber qué es un sistema numérico binario. Si no sabe nada al respecto o lo ha olvidado por completo, le sugerimos que primero lea el artículo Java: bits y bytes y recuerde a todos los demás que en el sistema numérico binario solo hay dos dígitos: 0 y 1, y todos los datos en la computadora se representa precisamente usando ceros y unos condicionales. Cualquiera de los números a los que estamos acostumbrados (decimales; para ellos existen 10 dígitos diferentes del 0 al 9, con los que escribimos cualquier número) se puede representar en el sistema numérico binario. Puede convertir un número decimal a binario mediante división secuencial en una columna utilizando el sistema numérico base (2). Los restos de la división en cada paso, escritos en orden inverso, nos darán el número binario deseado. Aquí, por ejemplo, se muestra la conversión del número decimal 103 a representación binaria: Operaciones lógicas en Java.  Operaciones bit a bit en Java - 3

Sistema de números binarios en el curso JavaRush

En el curso JavaRush, se habla sobre el sistema numérico binario mientras se estudia la misión MultiThreading (nivel 10, lección 1); después de la lección hay varias tareas para consolidar. Sin embargo, este tema no es nada difícil e incluso si aún no has llegado tan lejos en el curso, probablemente lo resolverás.

Además de y &Java también utiliza operadores bit a bit: |^
  • ~ operador de negación bit a bit
  • >>desplazamiento bit a bit a la derecha
  • >>>desplazamiento a la derecha bit a bit sin signo
  • <<desplazamiento bit a bit hacia la izquierda
Para los principiantes, los operadores bit a bit parecen muy confusos y artificiales. La mayoría de las veces no entienden para qué se les necesita, excepto para resolver problemas educativos. De hecho, se pueden utilizar como mínimo para organizar divisiones y multiplicaciones eficientes, y los profesionales los utilizan para codificar/decodificar, cifrar y generar números aleatorios.

Operadores bit a bit &, | y ^

Veamos un ejemplo de cómo funcionan estos operadores. Digamos que tenemos dos números enteros:
int a = 25;
int b = 112; 
Necesitamos aplicarles tres operaciones y &mostrar el resultado en la pantalla. Aquí está el código del 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);

   }
}
El resultado del programa es el siguiente:

a & b = 16
a | b = 121
a ^ b = 105
Si no entiendes lo que está pasando, el resultado parece muy, muy misterioso. De hecho, todo es más sencillo de lo que parece. Los operadores bit a bit "ven" los números de operandos en su forma binaria. Y luego aplican operadores lógicos &, |o ^a los dígitos (bits) correspondientes de ambos números. Entonces, porque &el último bit de la representación binaria del número 25 se suma lógicamente al último bit de la representación binaria del número 112, el penúltimo bit al penúltimo, y así sucesivamente: Operaciones lógicas en Java.  Operaciones bit a bit en Java - 4la misma lógica se puede rastrear en el caso de |y ^. Operaciones lógicas en Java.  Operaciones bit a bit en Java - 5

Desplazamiento de bits hacia la izquierda o hacia la derecha

Hay varios operadores de desplazamiento de bits en Java. Los operadores más utilizados <<son y >>. Desplazan la representación binaria de un número hacia la izquierda o hacia la derecha, respectivamente, y en el caso de un desplazamiento hacia la derecha, conservando el signo (explicaremos qué significa preservar el signo más adelante). Hay otro operador de desplazamiento a la derecha >>>. Hace lo mismo pero >>no guarda el cartel. Entonces, veamos su trabajo usando un ejemplo. int a = 13 a << 1desplaza todos los bits de la representación binaria del número a 1 bit hacia la izquierda. Para simplificar, imaginemos el número 13 en binario como 0000 1101. De hecho, este número se ve así: 00000000 00000000 00000000 00001101, ya que Java intasigna 4 bytes o 32 bits para los números. Sin embargo, esto no influye en el ejemplo, por lo que en este ejemplo consideraremos que nuestro número es de un byte. Operaciones lógicas en Java.  Operaciones bit a bit en Java - 6El bit que queda libre a la derecha se rellena con ceros. Como resultado de esta operación, obtenemos el número 26. a << 2Desplaza todos los bits de la representación binaria del número a2 bits hacia la izquierda, y los dos bits que quedan libres a la derecha se rellenan con ceros. Como resultado, obtendremos el número 52. a << 3El resultado será 104... ¿Notas el patrón? El desplazamiento bit a bit ahacia la izquierda en n posiciones funciona como multiplicar un número apor 2 elevado a n. Lo mismo se aplica a los números negativos. Esto -13 << 3dará el resultado -104. a >> ndesplaza la representación binaria de un número n posiciones hacia la derecha. Por ejemplo, 13 >> 1 transforma el número 1101 en el número 0110, es decir, 6. Y 13 >> 2el resultado será 3. Es decir, en esencia, aquí dividimos el número entre 2 elevado a n, donde n es el número de turnos. a la derecha, pero con una advertencia: si el número es impar, durante esta operación parece que restablecemos el último bit del número. Pero con los negativos la situación es algo diferente. Digamos que intenta comprobar qué producirá el programa si le pides que realice una operación -13 >> 1. Verá el número -7, no -6, como podría pensar. Esto sucede debido a la forma en que se almacenan los números negativos en Java y otros lenguajes de programación. Se almacenan en lo que se llama código complementario. En este caso, el dígito más significativo (el de la izquierda) se da debajo del signo. En el caso de un número negativo, el dígito más significativo es 1.

código adicional

Consideremos el número int a = 13. Si en el programa imprime su representación binaria en la consola usando el comando System.out.println(Integer.toBinaryString(a));, obtendremos 1101. De hecho, esta es una notación abreviada, ya que el número de tipo intocupa 4 bytes en la memoria, por lo que la computadora lo "ve" más. como esto:

00000000 00000000 00000000 00001101
El dígito más significativo es cero, lo que significa que tenemos un número positivo. Para traducir a código adicional:
  1. Escribimos el número -13 en el llamado “código directo”. Para ello, cambie el dígito más significativo del número a 1.
    Resultado de la acción:

    
    10000000 0000000 0000000 00001101
  2. A continuación, invertimos todos los bits (cambiamos 0 por 1 y 1 por 0) excepto el bit de signo. De hecho, ya lo hemos cambiado.
    Resultado de la acción:

    
    11111111 11111111 11111111 11110010

    (sí, los pasos 1 y 2 se podrían combinar, pero es mejor pensarlo así)

  3. Al número resultante se le suma 1.
    Resultado de la acción:

    
    11111111 11111111 11111111 11110011
El número binario resultante es -13, escrito en código complemento a dos, y el desplazamiento de bits (y otras operaciones) se le aplicarán específicamente. Es solo que la diferencia en la lógica de operación no se nota en todas las operaciones. Digamos que para el mismo desplazamiento hacia la izquierda la diferencia es imperceptible, podemos trabajar con números negativos de la misma forma que con números positivos. Ahora girémonos hacia la derecha -13 >> 1. Dado que nuestro operador >>conserva el signo, en esta operación todos los bits liberados a la izquierda no se rellenan con ceros, sino con unos. Por lo tanto, desplazando el número

11111111 11111111 11111111 11110011
un bit a la derecha, lo que da como resultado la siguiente secuencia de bits:

11111111 11111111 11111111 11111001
Si convertimos este número en código directo (es decir, primero restamos 1 y luego invertimos todos los bits excepto el primero) obtenemos el número:

10000000 00000000 00000000 00000111
o -7. Ahora que hemos entendido el operador de desplazamiento a la derecha que conserva el signo, quedará claro en qué se diferencia del operador >>>. a >>> n— esta operación es un desplazamiento sin signo, es decir, desplaza la representación binaria de un número ahacia la derecha en n bits, pero llena los n bits que quedan libres a la izquierda no con unos, como el operador >>, sino con ceros. Hagamos la operación -13 >>> 1. Ya tenemos el número -13en complemento a dos:

11111111 11111111 11111111 11110011
Al desplazarnos 1 bit hacia la derecha y llenar el bit libre con cero, obtenemos el siguiente número:

01111111 11111111 11111111 11111001
Lo que da el número en notación decimal 2147483641.

Operador de negación bit a bit ~

Este operador unario funciona de manera muy simple: invierte cada bit de la representación binaria de un número entero. Tomemos el número -13:

11111111 11111111 11111111 11110011
La operación de negación bit a bit ~13simplemente invertirá el valor de cada bit. Como resultado obtenemos:

00000000 00000000 00000000 00001100
O 12en forma decimal.

Breves conclusiones

  • Todos los operadores lógicos se aplican a expresiones booleanas, es decir, aquellas que se pueden decir que son verdaderas o falsas .
  • Si los operadores &, |o ^se aplican a números, ya no hablamos de operaciones lógicas, sino de bit a bit. Es decir, ambos números se convierten al sistema binario y a estos números se les aplican poco a poco las operaciones lógicas de suma, multiplicación o resta.
  • En lógica matemática, los operadores &y |corresponden a conjunción y disyunción.
  • El AND lógico es similar a multiplicar 1 ( verdadero ) y 0 ( falso ).
  • El OR lógico es similar a encontrar el máximo entre 1 ( verdadero ) y 0 ( falso ).
  • Para la negación bit a bit de un número entero a, se utiliza el operador ~a.
  • Para negar lógicamente una expresión booleana a, utilice el operador !a.
  • Los números negativos se almacenan y procesan en código complemento a dos.
  • Un desplazamiento bit a bit hacia la derecha puede >>conservar o no el signo ( >>>).
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION