- Operadores lógicos en Java
- Operador de negación lógica!
- AND lógico - &, así como AND condicional - &&
- El OR lógico es el operador |, así como el OR condicional es el operador ||
- XOR - O lógico exclusivo - operador ^
- Prioridad de las operaciones lógicas.
- Expresiones lógicas complejas
- Operadores bit a bit (bit a bit)
- Operadores bit a bit &, | y ^
- código adicional
- Operador de negación bit a bit ~
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 b
son 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 boolean
booleano, por ejemplo:
(2 < 1)
— operando lógico, su valor es falsotrue
- un operando lógico cuyo valor es obviamente verdaderoboolean a
- también puede ser un operando lógico, como booleano aint 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"
.
- Negación lógica , también conocida
NOT
como inversión. En Java, se indica con el!
símbolo " " antes del operando. Se aplica a un operando. - Lógico y , también es
AND
una 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 ,
XOR
estricta. 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 -&&
.
==
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 | !x significa "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. |
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 |
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 operandosa
o b
es falso , entonces la expresión a & b
será 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 |
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 & b
el operando en la expresión () a
es 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 | b
se 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 |
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 |
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:!
&
^
|
&&
||
&
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:q
nuestra variable es de tipo int
, pero q == 5
esta es una expresión booleana, y es igual a false , ya que arriba inicializamos con q
el 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:
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. |
&
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
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: la misma lógica se puede rastrear en el caso de |
y ^
.
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 << 1
desplaza 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 int
asigna 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. El bit que queda libre a la derecha se rellena con ceros. Como resultado de esta operación, obtenemos el número 26. a << 2
Desplaza todos los bits de la representación binaria del número a
2 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 << 3
El resultado será 104... ¿Notas el patrón? El desplazamiento bit a bit a
hacia la izquierda en n posiciones funciona como multiplicar un número a
por 2 elevado a n. Lo mismo se aplica a los números negativos. Esto -13 << 3
dará el resultado -104. a >> n
desplaza 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 >> 2
el 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úmeroint 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 int
ocupa 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:
-
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
-
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í)
- Al número resultante se le suma 1.
Resultado de la acción:11111111 11111111 11111111 11110011
-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 a
hacia 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 -13
en 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 ~13
simplemente invertirá el valor de cada bit. Como resultado obtenemos:
00000000 00000000 00000000 00001100
O 12
en 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 (>>>
).
GO TO FULL VERSION