Cosa sono gli operatori bit a bit?

Sono una persona che scrive codice solo per divertimento e non l’ha mai approfondito in un ambiente accademico o professionale, quindi roba come questi operatori bit a bit mi sfugge davvero.

Stavo leggendo un articolo su JavaScript, che apparentemente supporta operazioni bit a bit. Continuo a vedere questa operazione menzionata in alcuni punti, e ho provato a leggere per capire cosa sia esattamente, ma non riesco a capirlo affatto. Quindi cosa sono? Gli esempi chiari sarebbero grandiosi! : D

Solo alcune altre domande – quali sono alcune applicazioni pratiche di operazioni bit a bit? Quando potresti usarli?

Dal momento che nessuno ha affrontato il tema del perché questi sono utili:

Uso le operazioni bit a bit molto quando lavoro con le bandiere. Ad esempio, se si desidera passare una serie di flag a un’operazione (ad esempio, File.Open, con la modalità di lettura e la modalità di scrittura entrambe abilitate), è ansible passarli come un singolo valore. Ciò si ottiene assegnando a ogni flag ansible il proprio bit in un bitset (byte, short, int o long). Per esempio:

Read: 00000001 Write: 00000010 

Quindi se vuoi passare leggere e scrivere, passerai (LEGGI | WRITE) che poi combina i due in

 00000011 

Che poi può essere decriptato dall’altra parte come:

 if ((flag & Read) != 0) { //... 

quali controlli

 00000011 & 00000001 

che ritorna

 00000001 

che non è 0, quindi il flag specifica READ.

È ansible utilizzare XOR per alternare vari bit. L’ho usato quando si utilizza un flag per specificare gli input direzionali (Su, Giù, Sinistra, Destra). Ad esempio, se uno sprite si muove in orizzontale, e io voglio che giri:

  Up: 00000001 Down: 00000010 Left: 00000100 Right: 00001000 Current: 00000100 

Ho semplicemente XOR il valore corrente con (LEFT | RIGHT) che trasformsrà LEFT off e RIGHT on, in questo caso.

Bit Shifting è utile in diversi casi.

 x << y 

equivale a

x * 2 y

se hai bisogno di moltiplicare rapidamente per una potenza di due, ma fai attenzione a spostare un 1 bit nel bit più in alto - questo rende il numero negativo a meno che non sia senza segno. È anche utile quando si hanno a che fare con dimensioni di dati diverse. Ad esempio, leggendo un numero intero da quattro byte:

 int val = (A << 24) | (B << 16) | (C << 8) | D; 

Supponendo che A sia il byte più significativo e il meno importante. Sarebbe come:

 A = 01000000 B = 00000101 C = 00101011 D = 11100011 val = 01000000 00000101 00101011 11100011 

I colors vengono spesso memorizzati in questo modo (con il byte più significativo ignorato o utilizzato come Alpha):

 A = 255 = 11111111 R = 21 = 00010101 G = 255 = 11111111 B = 0 = 00000000 Color = 11111111 00010101 11111111 00000000 

Per trovare nuovamente i valori, basta spostare i bit a destra finché non si trova in fondo, quindi mascherare i bit rimanenti di ordine superiore:

 Int Alpha = Color >> 24 Int Red = Color >> 16 & 0xFF Int Green = Color >> 8 & 0xFF Int Blue = Color & 0xFF 

0xFF è lo stesso di 11111111. Quindi in sostanza, per Red, si farebbe questo:

 Color >> 16 = (filled in 00000000 00000000)11111111 00010101 (removed 11111111 00000000) 00000000 00000000 11111111 00010101 & 00000000 00000000 00000000 11111111 = 00000000 00000000 00000000 00010101 (The original value) 

Gli operatori bit a bit sono operatori che lavorano su un bit alla volta.

AND è 1 solo se entrambi i suoi input sono 1.

OR è 1 se uno o più dei suoi ingressi sono 1.

XOR è 1 solo se esattamente uno dei suoi ingressi è 1.

NOT è 1 solo se il suo input è 0.

Questi possono essere meglio descritti come tabelle di verità. Le possibilità di input sono in alto ea sinistra, il bit risultante è uno dei quattro (due nel caso di NOT dal momento che ha solo un input) valori mostrati all’intersezione dei due input.

 AND|0 1 OR|0 1 ---+---- ---+---- 0|0 0 0|0 1 1|0 1 1|1 1 XOR|0 1 NOT|0 1 ---+---- ---+--- 0|0 1 |1 0 1|1 0 

Un esempio è se si desidera solo i 4 bit più bassi di un numero intero, il valore AND con 15 (binario 1111):

  203: 1100 1011 AND 15: 0000 1111 ------------------ IS 11: 0000 1011 

Vale la pena notare che le tabelle di verità a bit singolo elencate come altre risposte funzionano solo su uno o due bit di input alla volta. Cosa succede quando si usano numeri interi, come ad esempio:

 int x = 5 & 6; 

La risposta sta nell’espansione binaria di ciascun input:

  5 = 0 0 0 0 0 1 0 1 & 6 = 0 0 0 0 0 1 1 0 --------------------- 0 0 0 0 0 1 0 0 

Ogni coppia di bit in ogni colonna viene eseguita attraverso la funzione “AND” per fornire il bit di uscita corrispondente sulla riga inferiore. Quindi la risposta all’espressione precedente è 4. La CPU ha eseguito (in questo esempio) 8 operazioni “AND” separate in parallelo, una per ogni colonna.

Lo dico perché ricordo ancora di avere questo “AHA!” momento in cui ho saputo di questo molti anni fa.

Questi sono gli operatori bit a bit, tutti supportati in JavaScript:

  • op1 & op2 – L’operatore AND confronta due bit e genera un risultato di 1 se entrambi i bit sono 1; in caso contrario, restituisce 0.

  • op1 | op2 op1 | op2 – L’operatore OR confronta due bit e genera un risultato di 1 se i bit sono complementari; in caso contrario, restituisce 0.

  • op1^ op2 – L’operatore EXCLUSIVE-OR confronta due bit e restituisce 1 se uno dei bit è 1 e dà 0 se entrambi i bit sono 0 o 1.

  • ~op1 – L’operatore C OMPLEMENT viene utilizzato per invertire tutti i bit dell’operando.

  • op1 << op2 - L'operatore SHIFT LEFT sposta i bit a sinistra, scarta il bit più a sinistra e assegna il bit più a destra al valore 0. Ogni spostamento a sinistra moltiplica effettivamente op1 per 2.

  • op1 >> op2 - The SHIFT RIGHT operatore The SHIFT RIGHT sposta i bit a destra, scarta il bit più a destra e assegna al bit più a sinistra un valore di 0. Ogni mossa a destra divide efficacemente op1 a metà. Il bit del segno più a sinistra viene conservato.

  • op1 >>> op2 - The SHIFT RIGHT operatore The SHIFT RIGHT - ZERO FILL sposta i bit a destra, scarta il bit più a destra e assegna il bit più a sinistra al valore 0. Ogni spostamento a destra divide efficacemente op1 a metà. Il bit del segno più a sinistra viene scartato.

Per rompere un po ‘di più, ha molto a che fare con la rappresentazione binaria del valore in questione.

 Ad esempio (in decimale):
 x = 8
 y = 1

 sarebbe venuto fuori (in binario):
 x = 1000
 y = 0001

 Da lì, puoi eseguire operazioni computazionali come "e" o "o";  in questo caso:
 x |  y = 
 1000 
 0001 |
 ------
 1001

 o ... 9 in decimale

Spero che questo ti aiuti.

Quando viene menzionato il termine “bitwise”, a volte si chiarisce che non è un operatore “logico”.

Ad esempio in JavaScript, gli operatori bit a bit trattano i loro operandi come una sequenza di 32 bit (zero e uno) ; nel frattempo, gli operatori logici vengono in genere utilizzati con valori booleani (logici) ma possono funzionare con tipi non booleani.

Prendi ad esempio expr1 e & expr2.

Restituisce expr1 se può essere convertito in falso; in caso contrario, restituisce expr2. Pertanto, se utilizzato con valori booleani, && restituisce true se entrambi gli operandi sono veri; in caso contrario, restituisce false.

 a = "Cat" && "Dog" // t && t returns Dog a = 2 && 4 // t && t returns 4 

Come altri hanno notato, 2 e 4 è un AND bit a bit, quindi restituirà 0.

Puoi copiare quanto segue in test.html o qualcosa di simile e testare:

    

Nella programmazione del computer digitale, un’operazione bit a bit opera su uno o più pattern di bit o numeri binari a livello dei singoli bit. È un’azione rapida e primitiva supportata direttamente dal processore e viene utilizzata per manipolare valori per confronti e calcoli. oprations

  • bit a bit AND

  • OR bit a bit

  • bit a bit NOT

  • XOR bit a bit

  • eccetera

Elemento dell’elenco

  AND|0 1 OR|0 1 ---+---- ---+---- 0|0 0 0|0 1 1|0 1 1|1 1 XOR|0 1 NOT|0 1 ---+---- ---+--- 0|0 1 |1 0 1|1 0 

Per esempio.

  203: 1100 1011 AND 15: 0000 1111 ------------------ = 11: 0000 1011 

Usi dell’operatore bit a bit

  • Gli operatori di spostamento a sinistra e di spostamento a destra sono equivalenti alla moltiplicazione e alla divisione di x * 2 y rispettivamente.

Per esempio.

 int main() { int x = 19; printf ("x << 1 = %d\n" , x <<1); printf ("x >> 1 = %d\n", x >>1); return 0; } // Output: 38 9 
  • L’operatore & può essere usato per controllare rapidamente se un numero è pari o dispari

Per esempio.

 int main() { int x = 19; (x & 1)? printf("Odd"): printf("Even"); return 0; } // Output: Odd 
  • Minimo di ricerca rapida di xey senza if else statuto

Per esempio.

 int min(int x, int y) { return y ^ ((x ^ y) & - (x < y)) } 
  • Conversione da decimale a binario

Per esempio.

 #include  int main () { int n , c , k ; printf("Enter an integer in decimal number system\n " ) ; scanf( "%d" , & n ); printf("%d in binary number system is: \n " , n ) ; for ( c = 31; c >= 0 ; c -- ) { k = n >> c ; if ( k & 1 ) printf("1" ) ; else printf("0" ) ; } printf(" \n " ); return 0 ; } 
  • La crittografia del gate XOR è una tecnica popolare, grazie alla sua compatibilità e al suo utilizzo da parte del programmatore.
    • l'operatore XOR bit a bit è l'operatore più utile dal punto di vista dell'intervista tecnica.

il cambio bitwuse funziona solo con il numero + ve

Inoltre, esiste una vasta gamma di utilizzo della logica bit a bit

Potrebbe essere utile pensarlo in questo modo. Ecco come AND (&) funziona:

Fondamentalmente dice che entrambi sono numeri, quindi se hai due numeri 5 e 3 saranno convertiti in binari e il computer penserà

  5: 00000101 3: 00000011 

sono entrambi uno: 00000001 0 è falso, 1 è vero

Quindi l’AND di 5 e 3 è uno. L’operatore OR (|) fa la stessa cosa tranne che uno solo dei numeri deve essere uno per l’uscita 1, non entrambi.

Continuavo a sentire quanto fossero lenti gli operatori bitwise di JavaScript. Ho fatto alcuni test per il mio ultimo post sul blog e ho scoperto che erano tra il 40% e l’80% più veloci dell’alternativa aritmetica in diversi test. Forse erano lenti. Nei browser moderni, li amo.

Ho un caso nel mio codice che sarà più veloce e più facile da leggere a causa di questo. Terrò gli occhi aperti per di più.