- Operatori logici in Java
- Operatore logico di negazione!
- AND logico - &, nonché AND condizionale - &&
- L'OR logico è l'operatore |, così come l'OR condizionale è l'operatore ||
- XOR - OR logico esclusivo - operatore ^
- Priorità delle operazioni logiche
- Espressioni logiche complesse
- Operatori bit a bit (bit a bit).
- Operatori bit a bit &, | e ^
- Codice aggiuntivo
- Operatore di negazione bit a bit ~
Operazioni logiche in Java
Le operazioni logiche vengono eseguite utilizzando operatori booleani. Scusate la tautologia, ma le cose stanno proprio così. Le operazioni logiche di base (in programmazione e matematica) possono essere applicate ad argomenti logici (operandi) e possono anche essere utilizzate per formare espressioni più complesse, simili alle operazioni aritmetiche sui numeri. Ad esempio l'espressione:
(a | b) | (c < 100) & !(true) ^ (q == 5)
è un'espressione logica complessa con quattro operandi: (a | b)
, dove а
e b
sono variabili di tipo boolean
(c < 100)
(true)
(q == 5)
. A sua volta, un'espressione logica semplice (a | b)
è composta anche da due argomenti di operando. Un operando logico è un'espressione che può essere definita vera o falsa, vera o falsa . Nel gergo Java, un operando booleano è un'espressione di tipo boolean
o booleano, ad esempio:
(2 < 1)
— operando logico, il suo valore è falsotrue
- un operando logico il cui valore è ovviamente veroboolean a
- può anche essere un operando logico, come il booleano aint a = 2
- non è un operando logico , è solo una variabile di tipoint
String a = "true"
inoltre non è un operando logico . Questa è una stringa il cui valore di testo è"true"
.
- Negazione logica , detta anche
NOT
inversione. In Java, è indicato dal!
simbolo “ ” prima dell'operando. Si applica a un operando. - Logico e , è anche
AND
una congiunzione. Indicato dal&
simbolo “ ” tra i due operandi a cui è applicato. - Logico o in Java , è anche -
OR
, è anche disgiunzione. In Java è indicato dal simbolo “|
” tra due operandi. - Disgiunzione esclusiva o rigorosa
XOR
. In Java è indicato dal simbolo “^
” tra due operandi. - In Java, gli operatori logici includono il condizionale o , indicato come
||
, così come il condizionale e -&&
.
==
non è considerato un operatore logico. Attenzione! In Java gli operatori logici&
,|
e^
si applicano anche agli interi. In questo caso funzionano in modo leggermente diverso e sono chiamati operatori logici bit a bit (o bit a bit). Su di loro - verso la fine dell'articolo. Diamo un'occhiata alla tabella con una breve descrizione di ciascuno degli operatori logici Java e di seguito li descriveremo in modo più dettagliato e forniremo esempi di codice.
operatore Java | Nome | Tipo | Breve descrizione | Esempio |
---|---|---|---|---|
! |
“Non” logico (negazione) | Unario | !x significa "non x". Restituisce vero se l'operando è falso . Restituisce falso se l'operando è vero . |
boolean x = true; Poi // !x == false |
& |
AND logico ( AND , moltiplicazione) |
Binario | Restituisce vero se entrambi gli operandi sono veri . | a = true; b = false; Poi a & b == false |
| |
OR logico ( OR , addizione) |
Binario | Restituisce vero se almeno uno degli operandi è vero . | a = true; b = false; Poi a | b == true |
^ |
OR logico esclusivo ( XOR ) |
Binario | Restituisce vero se uno e solo uno degli operandi è vero . Restituisce false se entrambi gli operandi sono true o false . In sostanza, restituisce true se gli operandi sono diversi. | a = true; b = false; Poi a ^ b == true |
&& |
AND condizionale (AND logico breve) | Binario | Uguale a , & ma se l'operando a sinistra di & è false , questo operatore restituisce false senza controllare il secondo operando. |
|
|| |
OR condizionale (OR logico breve) | Binario | Uguale a , | ma se l'operatore a sinistra è true , l'operatore restituisce true senza controllare il secondo operando. |
Operatore logico di negazione!
Questo operatore è unario, ovvero si applica a una singola espressione o operando booleano. È molto semplice da capire, come ogni negazione: l'operatore cambia semplicemente il significato dell'espressione nel suo opposto. Tabella della verità o risultati dell'esecuzione di un'operazione di negazione:Il valore di a | !UN |
falso | VERO |
VERO | falso |
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
}
}
L'output del programma sarà il seguente:
false
true
false
AND logico - &, nonché AND condizionale - &&
L'AND logico o la congiunzione viene applicata a due espressioni e il suo risultato sarà vero solo se entrambi gli operandi sono veri. Cioè, se uno degli operandia
or b
è false , l'espressione a & b
sarà false indipendentemente dal valore del secondo operatore. Se immagini che vero sia il numero 1 e falso sia 0, l'operatore &
funziona esattamente come una normale moltiplicazione. Pertanto, l’AND logico è spesso chiamato “moltiplicazione logica”. E, a proposito, questo fatto aiuta a ricordare rapidamente il funzionamento dell'operatore &
e a non confonderlo con l'operatore logico o |
. Tabella di verità AND, è anche il risultato del lavoro dell’operatore&
UN | B | a&b |
VERO | VERO | VERO |
VERO | falso | falso |
falso | VERO | 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); // 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
}
}
Risultato del programma:
false
true
false
false
L'operatore &&
è talvolta chiamato “AND breve”. Produce lo stesso risultato quando si lavora con operandi logici come operatore &
. Tuttavia, c'è una differenza nel suo lavoro stesso. Quindi, hai già notato che se a & b
l'operando nell'espressione ( ) a
è false , non ha senso verificare il valore dell'operando b
: il risultato dell'operazione sarà sicuramente false . Quindi se fondamentalmente non abbiamo bisogno del valore del secondo operando, utilizzandolo &&
riduciamo il numero di calcoli nel programma. Se sostituiamo tutti gli operatori dell'esempio &
con &&
, il risultato sarà esattamente lo stesso, ma il programma stesso girerà un po' più velocemente (anche se non ce ne accorgeremo, visto che stiamo parlando di mili-micro... insomma , unità di tempo molto piccole).
L'OR logico è l'operatore |, così come l'OR condizionale è l'operatore ||
L'operatore OR in Java è rappresentato dal simbolo|
. Un OR logico o una disgiunzione viene applicato a due espressioni e il suo risultato sarà falso se e solo se entrambi gli operandi sono falsi. Qui osserviamo in una certa misura la stessa immagine del caso dell'operatore &
, ma esattamente il contrario. Cioè, se almeno un operando è true , l'espressione a | b
è garantita indipendentemente dal valore del secondo operatore. Se &
si comporta come una moltiplicazione logica, allora OR è un'addizione logica, se immagini che vero sia 1 e falso sia 0. Ricorda solo che l'addizione logica funziona in modo diverso dall'addizione normale. 1 + 1 in questo caso non è uguale a 2, ma a 1 (il numero 2 semplicemente non esiste in questo sistema). A volte la disgiunzione viene intesa come il massimo tra 0 e 1, e in questo caso, se almeno un operando è uguale a 1 ( true ), otteniamo esattamente true . Tabella di verità OR, detta anche risultato dell'operatore |
:
UN | B | un | B |
VERO | VERO | VERO |
VERO | falso | VERO |
falso | VERO | VERO |
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); // 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);
}
}
Risultato:
false
true
true
true
Se utilizziamo l'operatore OR condizionale - ||
invece di |
, otterremo esattamente lo stesso risultato, ma, come nel caso dell'AND condizionale &&
, agirà in modo economico: se "incontriamo" il primo operando uguale a true , il valore di il secondo operando non viene controllato, ma immediatamente il risultato è vero .
XOR Java - OR logico esclusivo - operatore ^
XOR
, addizione modulo 2, XOR logico, sottrazione logica, disgiunzione rigorosa, complemento bit a bit... l'operatore ^
ha molti nomi nell'algebra booleana. Il risultato dell'applicazione di questo operatore a due operandi sarà vero se gli operandi sono diversi e falso se gli operandi sono uguali. Pertanto, è conveniente confrontarlo con la sottrazione di zeri ( false ) e unità ( true ). Tabella di verità XOR
, detta anche risultato dell'operatore ^
:
Booleano a | Booleano b | a^b |
VERO | VERO | falso |
VERO | falso | VERO |
falso | VERO | VERO |
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); // 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);
}
}
Risultato:
false
false
true
true
Priorità delle operazioni logiche
Come in matematica, anche in programmazione gli operatori hanno un ordine di esecuzione specifico quando compaiono nella stessa espressione. Gli operatori unari presentano vantaggi rispetto a quelli binari e la moltiplicazione (anche logica) rispetto all'addizione. Abbiamo classificato gli operatori logici più in alto nell'elenco, maggiore è la loro priorità:!
&
^
|
&&
||
&
e |
) hanno precedenza diversa:
public class Solution {
public static void main(String[] args) {
boolean a = true, b = true, c = false;
System.out.println(a | b & c);
}
Se dovessimo procedere da sinistra verso destra, cioè applicando prima l'operatore |
e poi - &
, otterremmo il valore false . Ma in effetti, se esegui questo programma, sarai sicuro che l'output sarà vero , poiché l'operatore logico AND &
avrà una priorità maggiore rispetto all'operatore logico OR |
. Per evitare confusione, è necessario ricordare cosa &
si comporta come una moltiplicazione e |
cosa si comporta come un'addizione. Puoi modificare l'ordine di priorità. Usa semplicemente le parentesi, proprio come in matematica a scuola. Modifichiamo leggermente il nostro codice di esempio:
public class Solution {
public static void main(String[] args) {
boolean a = true, b = true, c = false;
System.out.println((a|b)&c);
}
Che cosa succede? Per prima cosa usiamo l'addizione logica tra parentesi e poi la moltiplicazione. Il risultato sarà falso .
Espressioni logiche complesse
Naturalmente possiamo combinare espressioni e operatori booleani. Ricordiamo l'espressione dell'inizio dell'articolo:(a | b) | (c < 100) & !(true) ^ (q == 5)
Ora non sembra così spaventoso. Scriviamo un programma che ne visualizzi il valore, avendo precedentemente determinato i valori di a
, b
, с
e q
. Esempio di calcolo del valore di un'espressione booleana complessa
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
la nostra variabile è di tipo int
, ma q == 5
questa è un'espressione booleana, ed è uguale a false , poiché sopra abbiamo inizializzato con q
il numero 2. Lo stesso vale per la variabile c
. Questo numero è uguale a 25, ma (c < 100) è un'espressione booleana uguale a true . Il risultato di questo programma:
true
Le espressioni booleane complesse possono essere utilizzate per testare condizioni molto complesse e ramificate, ma non dovrebbero essere abusate: rendono il codice difficile da leggere.
Operatori bit a bit (bit a bit).
All'inizio dell'articolo abbiamo menzionato che gli operatori&
e possono essere utilizzati in relazione ai tipi interi Java. In questo caso sono operatori bit a bit. Sono anche chiamate bit a bit, poiché una cifra è un bit e queste operazioni funzionano specificamente con i bit. Naturalmente funzionano in modo leggermente diverso dagli operatori logici e per capire esattamente come è necessario sapere cos'è un sistema numerico binario. Se non ne sai nulla o lo hai completamente dimenticato, ti suggeriamo di leggere prima l'articolo Java: bit e byte e ricordare a tutti gli altri che nel sistema numerico binario ci sono solo due cifre: 0 e 1, e tutti i dati nel computer è rappresentato precisamente utilizzando zeri e uno condizionali. Qualsiasi numero a cui siamo abituati (decimale; per loro ci sono 10 cifre diverse da 0 a 9, con le quali scriviamo qualsiasi numero) può essere rappresentato nel sistema numerico binario. È possibile convertire un numero decimale in binario utilizzando la divisione sequenziale in una colonna utilizzando il sistema numerico base (2). I resti della divisione ad ogni passaggio, scritti in ordine inverso, ci daranno il numero binario desiderato. Ecco, ad esempio, la conversione del numero decimale 103 in rappresentazione binaria: |
^
Sistema di numerazione binaria nel corso JavaRush Nel corso JavaRush si parla del sistema di numerazione binario mentre si studia la ricerca MultiThreading (livello 10, lezione 1); dopo la lezione ci sono diversi compiti di consolidamento. Tuttavia, questo argomento non è affatto difficile e, anche se non sei ancora arrivato così lontano nel corso, probabilmente riuscirai a capirlo. |
&
, |
e ^
Java utilizza anche operatori bit a bit:
~
operatore di negazione bit a bit>>
spostamento bit a destra>>>
spostamento a destra bit per bit senza segno<<
spostamento bit a sinistra
Operatori bit a bit &, | e ^
Vediamo un esempio di come funzionano questi operatori. Diciamo che abbiamo due numeri interi:int a = 25;
int b = 112;
Dobbiamo applicare loro tre operazioni e &
visualizzare il risultato sullo schermo. Ecco il codice del programma: |
^
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);
}
}
Il risultato del programma è il seguente:
a & b = 16
a | b = 121
a ^ b = 105
Se non capisci cosa sta succedendo, il risultato sembra molto, molto misterioso. In realtà, tutto è più semplice di quanto sembri. Gli operatori bit a bit “vedono” i numeri degli operandi nella loro forma binaria. E poi applicano gli operatori logici &
o alle cifre corrispondenti (bit) di entrambi i numeri |
. ^
Quindi, poiché &
l'ultimo bit della rappresentazione binaria del numero 25 si somma logicamente con l'ultimo bit della rappresentazione binaria del numero 112, il penultimo bit con il penultimo, e così via: La stessa logica può essere rintracciata nel caso di |
e ^
.
Spostamento di bit a sinistra o a destra
Esistono diversi operatori di spostamento di bit in Java. Gli operatori più comunemente utilizzati<<
sono e >>
. Spostano la rappresentazione binaria di un numero rispettivamente a sinistra o a destra e, in caso di spostamento, a destra, preservandone il segno (spiegheremo più avanti cosa significa preservare il segno). C'è un altro operatore di spostamento a destra >>>
. Fa la stessa cosa ma >>
non salva il segno. Quindi, diamo un'occhiata al loro lavoro usando un esempio. int a = 13
a << 1
sposta tutti i bit della rappresentazione binaria del numero a a sinistra di 1 bit. Per semplificare, immaginiamo il numero 13 in binario come 0000 1101. In effetti, questo numero assomiglia a questo: 00000000 00000000 00000000 00001101, poiché Java int
alloca 4 byte o 32 bit per i numeri. Tuttavia, questo non ha alcun ruolo nell'esempio, quindi in questo esempio considereremo il nostro numero a un byte. Il bit lasciato libero a destra è pieno di zeri. Come risultato di questa operazione, otteniamo il numero 26. a << 2
Sposta tutti i bit della rappresentazione binaria del numero a
a sinistra di 2 bit e i due bit lasciati liberi a destra vengono riempiti di zeri. Di conseguenza, otterremo il numero 52. a << 3
Il risultato sarà 104... Notate lo schema? Lo spostamento bit a a
sinistra di n posizioni funziona come moltiplicare un numero a
per 2 alla potenza di n. Lo stesso vale per i numeri negativi. Questo -13 << 3
darà il risultato -104. a >> n
sposta la rappresentazione binaria di un numero n posizioni verso destra. Ad esempio, 13 >> 1
trasforma il numero 1101 nel numero 0110, cioè 6. E 13 >> 2
il risultato sarà 3. Cioè, in sostanza, qui dividiamo il numero per 2 alla potenza di n, dove n è il numero di turni a destra, ma con un avvertimento: se il numero è dispari, durante questa operazione ci sembra di resettare l'ultimo bit del numero. Ma con quelli negativi la situazione è leggermente diversa. Diciamo, prova a verificare cosa produrrà il programma se gli chiedi di eseguire un'operazione -13 >> 1
. Vedrai il numero -7, non -6, come potresti pensare. Ciò accade a causa del modo in cui i numeri negativi vengono memorizzati in Java e in altri linguaggi di programmazione. Sono memorizzati in quello che viene chiamato codice complementare. In questo caso la cifra più significativa (quella a sinistra) è riportata sotto il segno. Nel caso di un numero negativo, la cifra più significativa è 1.
Codice aggiuntivo
Consideriamo il numeroint a = 13
. Se nel programma stampi la sua rappresentazione binaria sulla console usando il comando System.out.println(Integer.toBinaryString(a));
, otterremo 1101. In realtà, questa è una notazione abbreviata, poiché il numero del tipo int
occupa 4 byte in memoria, quindi il computer lo "vede" di più come questo:
00000000 00000000 00000000 00001101
La cifra più significativa è zero, il che significa che abbiamo un numero positivo. Per tradurre in codice aggiuntivo:
-
Scriviamo il numero -13 nel cosiddetto “codice diretto”. Per fare ciò, modificare la cifra più significativa del numero in 1.
Risultato dell'azione:10000000 0000000 0000000 00001101
-
Successivamente, invertiamo tutti i bit (cambiamo 0 in 1 e 1 in 0) tranne il bit di segno. In effetti, lo abbiamo già cambiato.
Risultato dell'azione:11111111 11111111 11111111 11110010
(sì, i passaggi 1 e 2 potrebbero essere combinati, ma è meglio pensarla in questo modo)
- Al numero risultante aggiungi 1.
Risultato dell'azione:11111111 11111111 11111111 11110011
-13 >> 1
. Poiché il nostro operatore >>
preserva il segno, in questa operazione tutti i bit liberati a sinistra vengono riempiti non con zeri, ma con unità. Quindi, spostando il numero
11111111 11111111 11111111 11110011
un bit a destra, ottenendo la seguente sequenza di bit:
11111111 11111111 11111111 11111001
Se convertiamo questo numero in codice diretto (cioè prima sottraiamo 1, poi invertiamo tutti i bit tranne il primo) otteniamo il numero:
10000000 00000000 00000000 00000111
o -7. Ora che abbiamo compreso l'operatore di spostamento a destra che preserva il segno, diventerà chiaro in cosa differisce dall'operatore >>>
. a >>> n
— questa operazione è uno spostamento senza segno, ovvero sposta la rappresentazione binaria di un numero a
a destra di n bit, ma riempie gli n bit lasciati liberi a sinistra non con uno, come l'operatore >>
, ma con zeri. Facciamo l'operazione -13 >>> 1
. Abbiamo già il numero -13
in complemento a due:
11111111 11111111 11111111 11110011
Spostandoci a destra di 1 bit e riempiendo il bit libero con zero, otteniamo il seguente numero:
01111111 11111111 11111111 11111001
Cosa dà il numero in notazione decimale 2147483641
.
Operatore di negazione bit a bit ~
Questo operatore unario funziona in modo molto semplice: inverte ogni bit della rappresentazione binaria di un numero intero. Prendiamo il numero-13
:
11111111 11111111 11111111 11110011
L'operazione di negazione bit a bit ~13
invertirà semplicemente il valore di ciascun bit. Di conseguenza otteniamo:
00000000 00000000 00000000 00001100
Oppure 12
in forma decimale.
Brevi conclusioni
- Tutti gli operatori logici si applicano alle espressioni booleane, cioè a quelle che si possono dire vere o false .
- Se si applicano gli operatori
&
,|
o^
ai numeri, non si parla più di operazioni logiche, ma di operazioni bit per bit. Cioè, entrambi i numeri vengono convertiti nel sistema binario e le operazioni di addizione, moltiplicazione o sottrazione logica vengono applicate a questi numeri bit per bit. - Nella logica matematica gli operatori
&
e|
corrispondono a congiunzione e disgiunzione. - L'AND logico è simile alla moltiplicazione di 1 ( vero ) e 0 ( falso ).
- L'OR logico è simile a trovare il massimo tra 1 ( true ) e 0 ( false ).
- Per la negazione bit a bit di un intero a viene utilizzato l'operatore
~a
. - Per negare logicamente un'espressione booleana a, utilizzare l'operatore
!a
. - I numeri negativi vengono memorizzati ed elaborati nel codice del complemento a due.
- Uno spostamento bit a destra a destra può
>>
o meno preservare il segno (>>>
).
GO TO FULL VERSION