Bit operaties

Naast het rekenen met getallen is het ook mogelijk om gebruik te maken van bit operaties (bitwise operations). Dit zijn bewerkingen op binaire getallen die direct door de processor uitgevoerd kunnen worden en in sommige gevallen veel efficiënter zijn om toe te passen. Deze bewerkingen hebben effect op de individuele bits van een binaire waarde, vandaar de naam “bit operaties”.

AND

De AND functie (&) is een veelgebruikte functie die zorgt dat een bit hoog wordt als alle invoer bits hoog zijn. Een voorbeeld met enkele bits:

A & B = C Als A en B hoog zijn, wordt C ook hoog

Als we naar een voorbeeld met binaire getallen gaan kijken:

0000 1101 (13)
& 0010 0101 (37)
= 0000 0101 (5)

Dus: 13 & 37 = 5

 
De AND functie wordt ook vaak gebruikt in combinatie met een bit masker. Dit is een methode om te achterhalen of 1 of enkele specifieke bits in een binaire waarde hoog zijn:

0110 0100 binaire waarde
& 0000 0100 bit masker om het derde bit te testen
= 0000 0100 alleen de waarde van het derde bit blijft staan (in dit geval 1)

OR

De OR functie (|) zorgt ervoor dat een bit hoog wordt als 1 van de invoer bits hoog is. Dus:

A | B = C Als A of B hoog is, wordt C ook hoog

Een voorbeeld met getallen:

0000 0011 (3)
| 0100 1001 (73)
= 0100 1011 (75)

Dus: 3 | 73 = 75

Nog een voorbeeld:

0011 1011 (59)
| 1000 1001 (137)
= 1011 1011 (187)

Dus: 59 | 137= 187

XOR

De XOR functie (^) (exclusive OR) is een variant op de OR en zorgt dat een bit alleen hoog wordt als 1 van de invoer bits hoog is:

A ^ B = C Als A of B hoog is, wordt C hoog
Als A en B beide hoog of laag zijn, wordt C laag

Dus:

1 ^ 0 = 1
0 ^ 1 = 1
0 ^ 0 = 0g
1 ^ 1 = 0

Met getallen ziet dat er als volgt uit:

0010 1111 (47)
^ 0100 0110 (70)
= 0110 1001 (105)

Dus: 47 ^ 70 = 105

NOT

De NOT functie (~) maakt dat de waarde van elk bit wordt omgezet (geïnverteerd).

~A = B Als A hoog is, wordt B laag en andersom

Dit kan net als alle andere functies ook met binaire getallen.

~ 0101 0101 (85)
= 1010 1010 (170)

~ 1111 1011 (251)
= 0000 0100 (4)

Bit shifting

By bit verschuivingen worden letterlijk bits een plek opgeschoven om de waarde van een binair getal aan te passen. Daarbij wordt een onderscheid gemaakt tussen verschuiven naar links of naar rechts (left shift/right shift). Bij left shift worden alle bits 1 plaats naar links opgeschoven. Zie dit voorbeeld:

< 0001 0110 (22)
= 0010 1100 (44)

Alle bits zijn 1 plek naar links opgeschoven. De waarde was 22, na de shift is de nieuwe waarde 44. Bij verschuivingen naar rechts gebeurt het tegenover gestelde:

> 0110 1000 (104)
= 0011 0100 (52)

Zoals je kunt zien is naar links schuiven gelijk aan een vermenigvuldiging met 2, naar rechts schuiven een deling door 2. Als we 1 plaats naar links schuiven wordt het getal 2 keer groter. Schuiven we nog een plaats naar links, wordt het getal wederom 2 keer groter. Dus als we 2 plaatsen naar links schuiven wordt het getal 2^2 (2 in kwadraat) = 4 keer groter. Dit werkt zolang het geheugenbereik van het getal dit toelaat (een Byte kan bijvoorbeeld geen waarde groter dan 255 bevatten). Bits aan de rand die door het schuiven overbodig worden vallen weg. Aan de andere kant worden nullen toegevoegd.

< 0100 0001 (65)
= 1000 0010 (130)

Het meest linkse bit valt weg, rechts wordt een ‘0’ toegevoegd.

< 1000 0010 (130)
= 0000 0100 (4)

Ook hier valt het linkse bit weg (met de waarde ‘1’) en wordt rechts een 0 toegevoegd.

Zoals je ziet, de tweede verschuiving zorgt ervoor dat de waarde niet opnieuw verdubbeld (130 x 2 = 260), omdat het het bereik van een byte niet toereikend is. Wat nu overblijft is de waarde 4. Verschuiven naar links met n plaatsen komt overeen met vermenigvuldigen met 2^n, mits het databereik het toelaat.

Bij verschuivingen naar rechts worden links nullen toegevoegd.

> 0100 1101 (77)
= 0010 0110 (38)

Het meest rechter bit valt weg, links wordt een ‘0’ toegevoegd.

> 0010 0110 (38)
= 0001 0011 (19)

En ook hier.

Bij rechts verschuiven is er sprake van data verlies in het geval het een oneven getal betreft. Het meest rechter bit is in dat geval een ‘1’, die valt weg. Verschuiven naar rechts met n plaatsen komt overeen met delen door 2^n en afronden naar beneden.