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
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
Per esempio.
int main() { int x = 19; (x & 1)? printf("Odd"): printf("Even"); return 0; } // Output: Odd
if else
statuto Per esempio.
int min(int x, int y) { return y ^ ((x ^ y) & - (x < y)) }
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 ; }
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ù.