JavaRush /Java Blog /Random-IT /Operatori logici in Java

Operatori logici in Java

Pubblicato nel gruppo Random-IT
Operazioni logiche in Java.  Operazioni bit a bit in Java - 1

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 bsono 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 booleano booleano, ad esempio:
  • (2 < 1)— operando logico, il suo valore è falso
  • true- un operando logico il cui valore è ovviamente vero
  • boolean a- può anche essere un operando logico, come il booleano a
  • int 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".
In Java sono disponibili le seguenti operazioni logiche:
  • Negazione logica , detta anche NOTinversione. In Java, è indicato dal !simbolo “ ” prima dell'operando. Si applica a un operando.
  • Logico e , è anche ANDuna 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 - &&.
Nota: anche nella logica matematica si considera la relazione di equivalenza, cioè di uguaglianza. Tuttavia, in Java l'operatore di uguaglianza==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 !xsignifica "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.

Operazioni logiche nel corso JavaRush

Alle operazioni logiche non c'è scampo, e nel corso JavaRush compaiono fin dai primi livelli, insieme alle condizioni e al tipo di dato booleano. I programmatori imparano gradualmente a utilizzare i metodi della logica matematica. Per manipolazioni più sicure con costruzioni logiche, sono necessarie una certa destrezza e comprensione di determinati processi. Quindi queste operazioni vengono affrontate in modo più dettagliato e ad un livello completamente diverso alla fine della ricerca del multithreading, quando la maggior parte degli studenti non è più troppo distratta direttamente dalla sintassi e dalle costruzioni, ma cerca di approfondire l'essenza del compito.

Operazioni logiche in Java.  Operazioni bit a bit in Java - 2

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
Esempio. Operazione logica di negazione
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 operandi aor bè false , l'espressione a & bsarà 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
AND logico, è anche una congiunzione, esempi:
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 & bl'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
OR logico, noto anche come disgiunzione, esempio:
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
Esempio:
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à:
  1. !
  2. &
  3. ^
  4. |
  5. &&
  6. ||
Diamo un'occhiata agli esempi. Congiunzione e disgiunzione ( &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:qla nostra variabile è di tipo int, ma q == 5questa è un'espressione booleana, ed è uguale a false , poiché sopra abbiamo inizializzato con qil 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: |^Operazioni logiche in Java.  Operazioni bit a bit in Java - 3

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.

Oltre a &, |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
Ai principianti, gli operatori bit a bit sembrano molto confusi e artificiali. Molto spesso non capiscono a cosa servono, tranne che per risolvere problemi educativi. In effetti, possono essere utilizzati come minimo per organizzare divisioni e moltiplicazioni efficienti, e i professionisti li usano per codificare/decodificare, crittografare e generare numeri casuali.

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: Operazioni logiche in Java.  Operazioni bit a bit in Java - 4La stessa logica può essere rintracciata nel caso di |e ^. Operazioni logiche in Java.  Operazioni bit a bit in Java - 5

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 << 1sposta 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 intalloca 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. Operazioni logiche in Java.  Operazioni bit a bit in Java - 6Il bit lasciato libero a destra è pieno di zeri. Come risultato di questa operazione, otteniamo il numero 26. a << 2Sposta tutti i bit della rappresentazione binaria del numero aa sinistra di 2 bit e i due bit lasciati liberi a destra vengono riempiti di zeri. Di conseguenza, otterremo il numero 52. a << 3Il risultato sarà 104... Notate lo schema? Lo spostamento bit a asinistra di n posizioni funziona come moltiplicare un numero aper 2 alla potenza di n. Lo stesso vale per i numeri negativi. Questo -13 << 3darà il risultato -104. a >> nsposta 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 >> 2il 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 numero int 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 intoccupa 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:
  1. 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
  2. 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)

  3. Al numero risultante aggiungi 1.
    Risultato dell'azione:

    
    11111111 11111111 11111111 11110011
Il numero binario risultante è -13, scritto in codice in complemento a due, e lo spostamento di bit (e altre operazioni) verrà applicato specificatamente ad esso. È solo che la differenza nella logica di funzionamento non è evidente in tutte le operazioni. Diciamo che, per lo stesso spostamento a sinistra, la differenza è impercettibile; possiamo lavorare con i numeri negativi allo stesso modo che con i numeri positivi. Ora spostiamoci a destra -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 aa 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 -13in 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 ~13invertirà semplicemente il valore di ciascun bit. Di conseguenza otteniamo:

00000000 00000000 00000000 00001100
Oppure 12in 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 ( >>>).
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION