"Hej, Amigo!"
"Jeg vil også gerne tale om bitmasker og XOR."
"Du ved allerede, at tal består af bits, og du kan udføre forskellige operationer på disse bits. En bitmaske er en repræsentation af flere forskellige logiske værdier (sande/falske værdier) som et enkelt heltal. I dette tilfælde svarer hver boolsk værdi til en specifik smule. Sådan kunne det gøres:"
"Den binære repræsentation af potenser af to (1, 2, 4, 8, 16, 32, ...) involverer kun at indstille en bit:"
Nummer | Binær repræsentation |
---|---|
1 | 0000 0001 |
2 | 0000 0010 |
4 | 0000 0100 |
8 | 0000 1000 |
16 | 0001 0000 |
19 (ikke en topotens) | 0001 0011 |
31 (ikke en potens af to) | 0001 1111 |
"Så ethvert heltal kan behandles som en matrix af bits eller en matrix af booleske værdier."
"Sådan kan du gemme forskellige booleske værdier i ét tal:"
boolean a = true;
boolean b = false;
boolean c = true;
boolean d = false;
int result = 0;
if (a) result += 1; // 1 == 20 — bit 0
if (b) result += 2; // 2 == 21 — bit 1
if (c) result += 4; // 4 == 22 — bit 2
if (d) result += 8; // 8 == 23 — bit 3
"Nu er hver bit 1, hvis den tilsvarende booleske variabel var sand."
I vores tilfælde var variablerne a og c sande, så resultatet er lig med 1+4 == 5
0000 0101
0000 dcba
"Jeg tror, jeg ved, hvad der sker."
"Nå, hvis du forstår, så lad os komme videre."
"En int har 32 bit. En af dem bruges til tallets tegn, og den anden 31 kan bruges til at gemme værdierne af 31 booleske variabler."
"En lang har 64 bit, hvor vi kan gemme 63 booleske variabler."
"Ja."
"Snesevis af variabler proppet i ét tal. Det er en hel del."
"Men hvor anvendes dette?"
"Hovedsageligt i situationer, hvor du har brug for at gemme en masse information om objekter. Når du gemmer en masse information om et objekt, er der altid et par dusin booleske variabler. "Med denne tilgang er de alle bekvemt gemt i ét nummer ."
"Med vægt på ordet 'lagret'. For det er faktisk ikke så bekvemt at bruge nummeret."
"Det var i øvrigt lige det, jeg ville spørge. Hvordan udtrækker vi den boolske værdi fra tallet?"
"Det er overhovedet ikke kompliceret. Lad os sige, at du skal afgøre, om bit 6 er sat til 1 (2 i potensen af fem er 32). Vi kunne tjekke sådan her:"
int a = 32; // 25 == 0010 0000
int b = 8; // 23 == 0000 1000
int c = 2; // 21 == 0000 0010
int result = a + b + c; // 32 + 8 + 2 == 42 == 0010 1010
int a = result & 32; // 0010 1010 & 0010 0000 = 0010 0000
int b = result & 8; // 0010 1010 & 0000 1000 = 0000 1000
int c = result & 2; // 0010 1010 & 0000 0010 = 0000 0010
"Sådan involverer arbejdet med bitmasker tre operationer:"
1) Indstil en bestemt bit til 0
2) Indstil en bestemt bit til 1
3) Tjek værdien af den specifikke bit.
"Tag for eksempel bit 6."
"Hvordan sætter du bit 6 til 1?"
Kode | Beskrivelse |
---|---|
|
Hvordan indstiller du bit 6 til 1? |
|
Hvordan indstiller du bit 6 til 0? |
|
Hvordan får du værdien af bit 6? |
"Det er meget usædvanligt, men ikke svært. Mand, nu er jeg en hot-shot programmør."
"Og endnu et lille tip til, hvordan man nemt får tal med en bestemt bit sat til 0 eller 1: 01000000 eller 10111111."
Til dette har vi operatorerne >> og << .
"1 er 2 til nul potens. Med andre ord, et tal med bit 0 sat til 1. Vi har brug for et tal med bit 6 sat."
int c = 1 << 6; // 0000 0001 << 6 == 0100 0000 == 64
"Fedt! Det er virkelig nyttigt i sådanne tilfælde."
"Men hvad hvis jeg har brug for et tal, hvor hver bit er sat til 1 undtagen en bestemt bit er sat til 0?"
"Det er heller ikke svært:"
int d = ~(1 << 6); // ~0100 0000 == 10111111
"Med andre ord er det hele meget enkelt:"
Kode | Beskrivelse |
---|---|
|
Hvordan indstiller du bit 6 til 1? |
|
Hvordan indstiller du bit 6 til 0? |
|
Hvordan får du værdien af bit 6? |
"Det ser ikke særlig svært ud. Men jeg husker det ikke med det samme."
"Men hvis du støder på et skræmmende udtryk som "resultat &= ~(1 << 6)" i en andens kode, vil du vide, at denne person bare arbejder med en bitmaske."
"Og hvis du støder på det ofte, så vil det huske sig selv for dig."
"Husk sig selv... Det lyder godt. Tak for lektionen."
GO TO FULL VERSION