CodeGym /Java Blog /Random-IT /Operatori Java bit per bit
John Squirrels
Livello 41
San Francisco

Operatori Java bit per bit

Pubblicato nel gruppo Random-IT
Nella lezione di oggi, faremo conoscenza con gli operatori bitwise Java e prenderemo in considerazione esempi su come lavorare con essi. Probabilmente hai familiarità con la parola "bit". In caso contrario, ricordiamo cosa significa :) Un bit è la più piccola unità di informazione in un computer. Il suo nome deriva da cifra binaria . Un bit può essere espresso da uno di due numeri: 1 o 0. Esiste uno speciale sistema di numerazione binaria basato su uno e zero. Non ci addentreremo in una giungla matematica qui. Noteremo solo che qualsiasi numero in Java può essere convertito in forma binaria. Per fare ciò, è necessario utilizzare le classi wrapper.
Operatori bit a bit - 1
Ad esempio, ecco come puoi farlo per un int :

public class Main {

   public static void main(String[] args) {

       int x = 342;
       System.out.println(Integer.toBinaryString(x));
   }
}
Uscita console: 101010110 1010 10110 (ho aggiunto lo spazio per facilitarne la lettura) è il numero 342 nel sistema decimale. In realtà abbiamo scomposto questo numero in singoli bit: zero e uno. Le operazioni eseguite sui bit sono chiamate bit per bit .
  • ~ - NON bit a bit.
Questo operatore è molto semplice: passa sopra ogni bit del nostro numero e capovolge il bit: gli zeri diventano uno e gli uno diventano zero. Se lo applichiamo al nostro numero 342, ecco cosa succede: 101010110 è 342 rappresentato come un numero binario 010101001 è il valore dell'espressione ~342 Proviamo a metterlo in pratica:

public class Main {

   public static void main(String[] args) {

       int x = 342;
       System.out.println(~x);
   }
}
Output della console: 169 169 è il nostro risultato ( 010101001 ) nel familiare sistema decimale :)
  • & - AND bit a bit
Come puoi vedere, sembra abbastanza simile all'AND logico ( && ). L' operatore && , ricorderete, restituisce vero solo se entrambi gli operandi sono veri. Bitwise & funziona in modo simile: confronta due numeri bit per bit. Il confronto produce un terzo numero. Ad esempio, prendiamo i numeri 277 e 432: 110110000 è 277 rappresentato come numero binario 1000101011 è 432 rappresentato come numero binario Successivamente, l'operatore & confronta il primo bit del numero superiore con il primo bit del numero inferiore. Poiché si tratta di un operatore AND, il risultato sarà 1 solo se entrambi i bit sono 1. In ogni altro caso, il risultato è 0. 100010101 &Operatore & Per prima cosa confrontiamo i primi bit dei due numeri, poi i secondi bit, poi i terzi e così via. Come puoi vedere, solo in due casi entrambi i bit corrispondenti nei numeri sono uguali a 1 (il primo e il quinto bit). Tutti gli altri confronti hanno prodotto 0. Quindi alla fine abbiamo ottenuto il numero 10001000. Nel sistema decimale corrisponde al numero 272. Controlliamo:

public class Main {

   public static void main(String[] args) {
       System.out.println(277&432);
   }
}
Uscita console: 272
  • | - OR bit a bit.
Questo operatore funziona allo stesso modo: confrontando due numeri bit per bit. Solo ora se almeno uno dei bit è 1, allora il risultato è 1. Diamo un'occhiata agli stessi numeri (277 e 432): 100010101 | 110110000 _______________ 110110101 - risultato del | operatore Ecco che otteniamo un risultato diverso: gli unici bit che rimangono zeri sono quei bit che erano zeri in entrambi i numeri. Il risultato è il numero 110110101. Nel sistema decimale corrisponde al numero 437 Controlliamo:

public class Main {

   public static void main(String[] args) {
       System.out.println(277|432);
   }
}
Uscita console: 437 Abbiamo calcolato tutto correttamente! :)
  • ^ - XOR bit per bit (OR esclusivo)
Non abbiamo ancora incontrato questo operatore. Ma non c'è niente di complicato in questo. È simile al normale operatore OR. C'è una differenza: l'OR ordinario restituisce vero se almeno un operando è vero. Ma non deve essere uno: se entrambi gli operandi sono veri, il risultato è vero. Ma l'OR esclusivo restituisce vero solo se esattamente uno degli operandi è vero. Se entrambi gli operandi sono veri, l'OR ordinario restituisce vero ("almeno un vero"), ma XOR restituisce falso. Ecco perché si chiama OR esclusivo. Sapendo come funzionano i precedenti operatori bit per bit, puoi probabilmente calcolare facilmente 277 ^ 432. Ma approfondiamolo insieme ancora una volta :) 100010101 ^ 110110000 _______________ 010100101 - risultato di ^operatore Questo è il nostro risultato. Quei bit che erano gli stessi in entrambi i numeri producono uno 0 (il che significa che il test "solo uno" è fallito). Ma i bit che formavano una coppia 0-1 o 1-0 sono diventati uno. Il nostro risultato è il numero 010100101. Nel sistema decimale corrisponde al numero 165. Vediamo se i nostri calcoli sono corretti:

public class Main {

   public static void main(String[] args) {
       System.out.println(277^432);
   }
}
Uscita console: 165 Super! Tutto è proprio come pensavamo :) Ora è il momento di familiarizzare con gli operatori bit shift. Il nome parla da sé. Prendiamo un numero e spostiamo i suoi bit a sinistra oa destra :) Vediamo come appare:

Sposta a sinistra

Uno spostamento di bit a sinistra è indicato da << Ecco un esempio:

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 3;// Shift distance

       int z = (x << y);
       System.out.println(Integer.toBinaryString(x));
       System.out.println(Integer.toBinaryString(z));
   }
}
In questo esempio, il numero x = 64 è chiamato valore. Sono i bit del valore che sposteremo. Sposteremo i bit a sinistra (potreste averlo indovinato dalla direzione dell'operatore << ) Nel sistema binario, il numero 64 = 1000000 Il numero y = 3 è chiamato distanza di spostamento. La distanza di spostamento indica di quanti bit a destra/sinistra vuoi spostare i bit del numero x Nel nostro esempio, li spostiamo di 3 bit a sinistra. Per vedere più chiaramente il processo di spostamento, guarda l'immagine. In questo esempio, usiamo int s. Gli int occupano 32 bit nella memoria del computer. Ecco come appare il nostro numero 64 originale:
Operatori bit a bit - 2
E ora prendiamo ciascuno dei nostri bit e li spostiamo letteralmente a sinistra di 3 posizioni:
Operatori bit a bit - 3
Dai un'occhiata a quello che abbiamo. Come puoi vedere, tutti i nostri bit si sono spostati e sono stati aggiunti altri 3 zeri dal limite dell'intervallo. Tre, perché abbiamo spostato di 3. Se avessimo spostato di 10, sarebbero stati aggiunti 10 zeri. Pertanto, l'espressione x << y significa "sposta i bit del numero x a sinistra di y posizioni". Il risultato della nostra espressione è il numero di 1000000000, che è 512 nel sistema decimale. Controlliamo:

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 3;// Shift distance

       int z = (x << y);
       System.out.println(z);
   }
}
Uscita console: 512 Perfetto! Teoricamente, i bit potrebbero essere spostati all'infinito, ma poiché il nostro numero è un int , abbiamo a disposizione solo 32 cifre binarie. Di questi, 7 sono già occupati da 64 (1000000). Pertanto, se ci spostiamo di 27 posizioni a sinistra, il nostro unico si sposterà oltre l'intervallo del tipo di dati e andrà perso. Rimarrebbero solo zeri!

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 26;// Shift distance

       int z = (x << y);
       System.out.println(z);
   }
}
Uscita console: 0 Come previsto, quella è andata oltre i 32 bit disponibili ed è scomparsa. Abbiamo concluso con un numero a 32 bit composto da soli zeri.
Operatori bit per bit - 4
Naturalmente, questo corrisponde a 0 nel sistema decimale. Ecco una semplice regola per ricordare gli spostamenti a sinistra: Per ogni spostamento a sinistra, il numero viene moltiplicato per 2. Proviamo a calcolare la seguente espressione senza immagini di bit 111111111 << 3 Dobbiamo moltiplicare il numero 111111111 per 2 . Di conseguenza, otteniamo 888888888. Scriviamo del codice e controlliamo:

public class Main {

   public static void main(String[] args) {
       System.out.println(111111111 << 3);
   }
}
Uscita console: 888888888

Sposta a destra

Questa operazione è denotata da >> . Fa la stessa cosa, ma nella direzione opposta! :) Non reinventeremo la ruota. Proviamo con lo stesso int 64.

public class Main {

   public static void main(String[] args) {
       int x = 64;//value
       int y = 2;// Shift distance

       int z = (x >> y);
       System.out.println(z);
   }
}
Operatori bit per bit - 5
Operatori bit a bit - 6
Come risultato di uno spostamento a destra di 2, i due zeri estremi del nostro numero si spostano fuori portata e vengono persi. Otteniamo 10000, che corrisponde al numero 16 nel sistema decimale Output della console: 16 Ecco una semplice regola per ricordare gli spostamenti a destra: ogni spostamento a destra divide per due, scartando qualsiasi resto. Ad esempio, 35 >> 2 significa che dobbiamo dividere 35 per 2 due volte, scartando i resti 35/2 = 17 (scarta il resto 1) 17/2 = 8 (scarta il resto 1) Alla fine, 35 >> 2 dovrebbe essere uguale a 8. Verifichiamo:

public class Main {

   public static void main(String[] args) {
       System.out.println(35 >> 2);
   }
}
Uscita console: 8

Precedenza dell'operatore in Java

Durante la scrittura e la lettura del codice, troverai spesso espressioni che combinano diverse operazioni. È molto importante capire l'ordine in cui verranno eseguiti (altrimenti potresti rimanere sorpreso dal risultato) Poiché Java ha molte operazioni, a ciascuna di esse è stato assegnato un posto in una tabella speciale:

Precedenza dell'operatore

Operatori Precedenza
suffisso espr++ espr--
unario ++espr --espr +espr ~ !
Moltiplicativo * / %
additivo + -
spostare << >> >>>
relazionale < > <= >= istanza di
uguaglianza == !=
AND bit a bit &
OR esclusivo bit per bit ^
OR inclusivo bit per bit |
AND logico &&
OR logico ||
ternario ? :
Incarico = += -= *= /= %= &= ^= |= <<= >>= >>>=
Tutte le operazioni vengono eseguite da sinistra a destra, tenendo conto della loro precedenza. Ad esempio, se scriviamo

int x  = 6 - 4/2;
quindi l'operazione di divisione ( 4/2 ) verrà eseguita per prima. Anche se arriva secondo, ha la precedenza più alta. Le parentesi e le parentesi indicano la massima precedenza. Probabilmente te lo ricordi da scuola. Ad esempio, se li aggiungi all'espressione

int x  = (6 - 4)/2;
quindi la sottrazione viene eseguita per prima, poiché è racchiusa tra parentesi. La precedenza dell'operatore logico && è piuttosto bassa (vedere la tabella), quindi di solito sarà l'ultima. Per esempio:

boolean x = 6 - 4/2 > 3 && 12*12 <= 119;
Questa espressione verrà eseguita come segue:
  • 4/2 = 2

boolean x = 6 - 2 > 3 && 12*12 <= 119;
  • 12*12 = 144

boolean x = 6 - 2 > 3 && 144 <= 119;
  • 6-2 = 4

boolean x = 4 > 3 && 144 <= 119;
Successivamente, vengono eseguiti gli operatori di confronto:
  • 4 > 3 = vero

boolean x = true && 144 <= 119;
  • 144 <= 119 = falso

boolean x = true && false;
Infine, l'operatore AND ( && ) verrà eseguito per ultimo.

boolean x = true && false;
boolean x = false;
Ad esempio, l'operatore di addizione( + ) ha una precedenza maggiore rispetto all'operatore di confronto != (non uguale); Pertanto, nell'espressione

boolean x = 7 != 6+1;
prima verrà eseguita l'operazione 6+1, poi il controllo 7 != 7 (che restituisce falso), e infine l'assegnazione del risultato (falso) alla variabile x (l'assegnazione ha generalmente la precedenza più bassa di tutti gli operatori; vedere la tavola). Uff! È stata una grande lezione, ma ce l'hai fatta! Se non hai compreso appieno alcune di queste lezioni o di quelle precedenti, non preoccuparti. Toccheremo questi argomenti più di una volta in futuro. Un paio di lezioni di CodeGym sulle operazioni logiche e numeriche. Non ci arriveremo presto, ma non c'è niente di male se li leggi adesso.
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION