Operatori Swift Bitwise e Bit Shift (con esempi)

In questo tutorial imparerai a conoscere diverse operazioni bit per bit in Swift. Vengono utilizzati per il calcolo a livello di bit in un'espressione.

Un bit è usato per denotare una cifra binaria. Una cifra binaria può avere due possibili valori 0 o 1. Come programmatore di livello principiante, non devi lavorare con le operazioni a livello di bit.

È sufficiente lavorare con tipi di dati primitivi come: intero, float, booleano, stringa ecc. Potrebbe essere necessario lavorare a livello di bit quando si ha a che fare con la programmazione di basso livello.

Swift fornisce un ricco set di operatori, oltre agli operatori di base, per manipolare i bit. Questi operatori sono simili agli operatori logici, tranne per il fatto che lavorano su rappresentazioni binarie di dati (bit).

Gli operatori bit a bit sono operatori utilizzati per modificare i singoli bit di un operando. L'operando è una variabile o una costante in cui viene eseguita l'operazione.

Tutti gli operatori bit per bit disponibili in swift sono elencati di seguito:

1. Operatore NOT bit per bit

È rappresentato dal ~segno tilde e può essere applicato su un singolo operando. Questo inverte tutti i bit. cioè cambia 1 in 0 e 0 in 1.

Se x è una variabile / costante che contiene un valore binario, ovvero 0 o 1. L'operazione not bit per bit sulla variabile x può essere rappresentata nella tabella seguente:

NON
X ~ x
0 1
1 0

Esempio 1: operatore NOT bit per bit per numeri interi senza segno

 let initalNumber:UInt8 = 1 let invertedNumber = ~initalNumber print(invertedNumber) 

Quando esegui il programma sopra, l'output sarà:

 254

Nel programma precedente, l'istruzione let initalNumber:UInt8 = 1è di tipo Unsigned int di dimensione 8 bit. Quindi, 1 in decimale può essere rappresentato come 00000001in binario.

L'operatore bit per bit non cambia tutti i bit di una variabile o costante, il bit 0 viene modificato in 1 e 1 in 0. Quindi invertedNumber contiene bit 11111110. Dopo averlo convertito in decimale, viene rappresentato come 254. Quindi, l'istruzione print(invertedNumber)restituisce 254 nello schermo.

Puoi anche eseguire l'operatore bit per bit direttamente nei bit come:

Esempio 2: operatore NOT bit per bit in bit

 let initialBits: UInt8 = 0b11111111 let invertedBits = ~initialBits print(invertedBits) 

Quando esegui il programma sopra, l'output sarà:

 0

initialBits contiene un valore binario 11111111che corrisponde a 255 in decimale. Per rappresentare il numero in binario abbiamo 0bcome prefisso nel letterale. Senza 0bun prefisso, lo tratterà come un normale intero e riceverai un errore di overflow (UInt8 può memorizzare solo numeri da 0 a 255).

Poiché abbiamo utilizzato l'operatore not bit per bit, cambia tutto l'1 in 0. Quindi, la costante invertedBits contiene 00000000che è equivalente a 0 in UInt8.

Esempio 3: operatore NOT bit per bit per intero con segno

 let initalNumber:Int = 1 let invertedNumber = ~initalNumber print(invertedNumber) 

Quando esegui il programma sopra, l'output sarà:

 -2

Nel programma sopra, 1 in decimale può essere rappresentato come 00000001in binario. L'operatore bit per bit non cambia tutti i bit di una variabile o costante, il bit 0 viene modificato in 1 e 1 in 0. Quindi, invertedNumber contiene bit 11111110. Questo dovrebbe visualizzare 254 sullo schermo. Ma invece restituisce -2. Strano, vero ?? Esploriamo di seguito come è successo.

let initalNumber:Int = 1è un int con segno che può contenere interi positivi e negativi. Ecco perché quando abbiamo applicato l'operatore not per un intero con segno, il binario restituito può anche rappresentare un numero negativo.

Come ha interpretato il compilatore -2 come 11111110 in binario?

Il compilatore ha utilizzato il complemento di due per rappresentare i numeri interi. Per ottenere la notazione negativa del complemento a due di un intero, è necessario prima scrivere il numero in binario, quindi invertire le cifre e aggiungere uno al risultato.

Passaggi per scoprire il complemento di due di -2 :

  1. Scrivi 2 in formato binario: 00000010
  2. Inverti le cifre. 0 diventa 1 e 1 diventa 0:11111101
  3. Aggiungi 1: 11111110

È così che il compilatore interpreta il numero binario 1111110come -2in decimale. Ma c'è una piccola svolta fatta da quel compilatore che non abbiamo notato. Ha anche dedotto il tipo di invertedNumber come Int8tipo.

Per capire questo, vediamo un esempio di seguito:

 print(Int8(bitPattern: 0b11111110)) print(0b11111110)

Quando esegui il programma sopra, l'output sarà:

 -2 254

Nell'esempio precedente, il compilatore ha trattato il numero binario in -2 in decimale solo per il numero intero a 8 bit con segno. Pertanto l'istruzione print(Int8(bitPattern: 0b11111110))restituisce -2 sullo schermo.

Ma per il normale tipo intero la cui dimensione è 32/64 bit e può contenere valori elevati, interpreta il valore come 254. Pertanto, l'istruzione print(0b11111110)restituisce 254 nella schermata.

2. Operatore AND bit per bit

È rappresentato da &e può essere applicato su due operandi. L'operatore AND confronta due bit e restituisce 1 se entrambi i bit sono 1, altrimenti restituisce 0.

Se x e y sono variabili / costanti che contengono un valore binario, cioè 0 o 1. L'operazione AND bit per bit su x e y può essere rappresentata nella tabella seguente:

E
X y x & y
0 0 0
0 1 0
1 1 1
1 0 0

Esempio 5: operazione AND bit per bit

 let xBits = 0b10000011 let yBits = 0b11111111 let result = xBits & yBits print("Binary:",String(result, radix: 2)) print(result)

Quando esegui il programma sopra, l'output sarà:

 Binario: 10000011 131 

Nel programma precedente, l'istruzione let result = xBits & yBitscombina i bit di due operandi xBits e yBits. Restituisce 1 se entrambi i bit sono 1 altrimenti restituisce 0.

String(value , radix: )l'inizializzatore viene utilizzato per rappresentare il numero in un sistema numerico diverso. Se forniamo valore radice 2. Converte il numero in un sistema numerico binario. Allo stesso modo, possiamo usare 16 per esadecimale e 10 per decimale.

L'istruzione print("Binary:",String(result, radix: 2))restituisce Binary: 10000011 nella schermata. 10000011è equivalente a 131 in decimale, l'istruzione print(result)restituisce 131 nella console.

3. Operatore OR bit per bit

È rappresentato come |e può essere applicato su due operandi. L'operatore OR bit per bit confronta due bit e genera un risultato di 1 se uno o più dei suoi ingressi sono 1 altrimenti 0.

Se xey sono variabili / costanti che contengono un valore binario cioè 0 o 1. L'operazione OR bit per bit su xey può essere rappresentata nella tabella seguente:

O
X y x | y
0 0 0
0 1 1
1 1 1
1 0 1

Esempio 6: operazione OR bit per bit

 let xBits = 0b10000011 let yBits = 0b11111111 let result = xBits | yBits print("Binary:", String(result, radix: 2)) print(result) 

Quando esegui il programma sopra, l'output sarà:

 Binario: 11111111 255 

Nel programma precedente, l'istruzione let result = xBits | yBitscombina i bit di due costanti xBits e yBits. Restituisce 1 se uno qualsiasi dei bit è 1, altrimenti restituisce 0.

L'istruzione print("Binary:",String(result, radix: 2))restituisce Binary: 11111111 nella schermata. Poiché, 11111111è equivalente a 255in decimale, l'istruzione print(result)restituisce 255 nella schermata.

4. Operatore XOR bit per bit

È rappresentato come ^e può essere applicato su due operandi. L'operatore XOR confronta due bit e genera un risultato di 1 se esattamente uno dei suoi ingressi è 1, altrimenti restituisce 0.

Se xey sono variabili / costanti che contengono un valore binario cioè 0 o 1. L'operazione XOR bit per bit su xey può essere rappresentata nella tabella seguente:

XOR
X y x y
0 0 0
0 1 1
1 1 0
1 0 1

Esempio 7: operazione XOR bit per bit

 let xBits = 0b10000011 let yBits = 0b11111111 let result = xBits yBits print("Binary:", String(result, radix: 2)) print(result) 

Quando esegui il programma sopra, l'output sarà:

 Binario: 1111100124 

Nel programma precedente, l'istruzione let result = xBits yBitscombina i bit di due costanti xBits e yBits. Restituisce 1 se esattamente uno dei bit è 1, altrimenti restituisce 0.

L'istruzione print("Binary:",String(result, radix: 2))restituisce Binary: 1111100 (equivalente a 01111100) nella schermata. Poiché, 1111100è equivalente a 124in decimale, l'istruzione print(result)restituisce 124 nella schermata.

5. Operatore di spostamento bit per bit

Questi operatori vengono utilizzati per spostare tutti i bit di un numero a sinistra oa destra di un certo numero di posizioni e possono essere applicati su un singolo operando. È rappresentato come <<o >>.

Esistono due tipi di operatori di turno:

Operatore di spostamento a sinistra bit per bit

  • Indicato come <<
  • Fa sì che i bit vengano spostati a sinistra specificati dal numero seguito da <<.
  • Le posizioni dei bit che sono state lasciate libere dall'operazione di spostamento vengono riempite con zero.
  • Spostando i bit di un intero a sinistra di una posizione si raddoppia il suo valore

Esempio 8: operatore di spostamento a sinistra bit per bit

 let someBits:UInt8 = 0b11000100 print(someBits << 1) 

Quando esegui il programma sopra, l'output sarà:

 136

Nel programma precedente, abbiamo utilizzato l'operatore di spostamento a sinistra. Usare <<1 significa spostare il bit di 1 a sinistra. Le cifre vengono spostate a sinistra di una posizione e l'ultima cifra a destra viene riempita con uno zero.

Puoi anche vedere la cifra che viene spostata "fuori dalla fine" dal lato sinistro è persa. Non si avvolge di nuovo da destra. Spostandolo di un bit a sinistra si rimuove l'1 dal binario e si aggiunge 0 a destra per riempire il valore spostato, così come il resto degli altri bit viene spostato verso la posizione sinistra di 1.

Ciò restituisce 10001000che è equivalente a 136in UInt8. Pertanto, l' print(someBits << 1)istruzione restituisce 136 nella schermata.

Operatore di spostamento a destra bit per bit

  • Indicato come >>
  • Fa sì che i bit vengano spostati a destra del numero seguito da >>
  • Per i numeri senza segno, le posizioni dei bit che sono state liberate dall'operazione di spostamento vengono riempite con zero.
  • Per i numeri con segno (numeri che possono anche essere negativi), il bit di segno viene utilizzato per riempire le posizioni di bit libere. In altre parole, se il numero è positivo, viene utilizzato 0 e se il numero è negativo, viene utilizzato 1.
  • Spostandolo a destra di una posizione si dimezza il suo valore.

Esempio 9: operatore di spostamento a destra bit per bit per interi senza segno

 let someBits: UInt8 = 4 print(someBits>> 1) 

Quando esegui il programma sopra, l'output sarà:

 2

Nel programma precedente, abbiamo utilizzato l'operatore di spostamento a destra su un numero intero senza segno. Usare >>1 significa spostare il bit di 1 a destra. Le posizioni dei bit che sono state lasciate libere dall'operazione di spostamento sono sempre riempite con zero su un numero intero senza segno.

Poiché, 4 è rappresentato come 00000100in binario. Spostandolo di un bit a destra, restituisce 00000010che è equivalente a 2in UInt8. Pertanto, l' print(someBits>> 1)istruzione emette 2 sullo schermo.

Esempio 10: operatore di spostamento a destra bit per bit per intero con segno

 let someBits:Int = -4 print(someBits>> 1) 

Quando esegui il programma sopra, l'output sarà:

 -2

Nel programma precedente, abbiamo utilizzato l'operatore di spostamento a destra su un numero intero senza segno. A differenza dei numeri positivi, utilizzando >>per i numeri negativi, 1 viene utilizzato per riempire il posto vacante, invece di 0.

Poiché, -4è rappresentato come 11111100in binario. Spostandolo di un bit a destra e mettendo 1 in posizione vacante, restituisce 11111110che è equivalente a -2per Int8type. Pertanto, l' print(someBits>> 1)istruzione restituisce -2 nella schermata.

Articoli interessanti...