Bitmanipulation für Anfänger
Wer MBI in Bielefeld bei Prof. Dr. rer. nat. K.-U. Kettner studiert, braucht bestimmt dieses Wissen[1]:
Contents
Von Bits und Bytes
Daten-Typen (Variablen-Typen)
- 1 Bit ist die kleinste Einheit
- 1 Bit kann nur 2 Werte annehmen: 0 oder 1 (false oder true)
- Beispiel: 0
- Beispiel: 1
- 1 Byte...
- ...hat 8 Bit
- ein Byte kann 256 (2 hoch 8) Werte annehmen: 0 bis 255
- Beispiel: 0 0 0 0 0 0 0 0 ist der Wert 0
- Beispiel: 1 0 0 0 0 0 0 0 ist der Wert 128
- Beispiel: 1 0 0 0 0 0 0 1 ist der Wert 129
- Beispiel: 1 1 1 1 1 1 1 1 ist der Wert 255
- 1 Integer[2]
- hat 4 Byte (32 Bit)
- kann 4.294.967.296 (2 hoch 32) Werte annehmen: −2.147.483.648 bis 2.147.483.647
- Beispiele
- 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 ist der Wert 0
- 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 1 ist der Wert 1
- 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 0 1 ist der Wert 256
- 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 ist der Wert 65.536
- 0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 ist der Wert 16.777.216
- 0 1 1 1 1 1 1 1 | 1 1 1 1 1 1 1 1 | 1 1 1 1 1 1 1 1 | 1 1 1 1 1 1 1 1 ist der Wert 2.147.483.647
Über die Bits eines Bytes oder Integers
- Das rechteste Bit eines Bytes oder Integers nennt man das LeastSignificantBit[3].
- Das linkeste Bit eines Bytes oder Integers nennt man das MostSignificantBit[4].
- Die Wertigkeit der Bit wird genau wie im Dezimal-System vergeben (Basis hoch Stelle)...
- Dezimal-System (Basis 10)
- Jede Stelle kann 10 Werte annehmen: 0 bis 9 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
- Beispiel 1: Die Zahl 1111, also Eintausendeinhundertelf hat 4 Stellen, die rechteste (LSB) Stelle hat dendieWertigkeit 1 (10 hoch 0), die linkeste 1000 (10 hoch 3), somit ist der Dezimalwert: 1 * 1000 + 1 * 100 + 1 * 10 + 1 * 1 = 1111 (dezimal)
- Beispiel 2: Die Zahl 1211, also Eintausendzweihundertelf hat den Dezimalwert: 1 * 1000 + 2 * 100 + 1 * 10 + 1 * 1 = 1211
Das alles lässt sich genauso auch auf das Binärsystem anwenden:
- Binär-System (Basis 2)
- Jede Stelle kann 2 Werte annehmen: 0 bis 1 (0, 1)
- Beispiel 1: Die Zahl 1111, also (NICHT Eintausendeinhundertelf) hat 4 Stellen, die rechteste (LSB) Stelle hat die Wertigkeit 1 (2 hoch 0), die linkeste (MSB) 8 (2 hoch 3), somit ist der Dezimalwert: 1 * 8 + 1 * 4 + 1 * 2 + 1 * 1 = 15 (dezimal)
- Beispiel 2: Die Zahl 10000001, hat 8 Stellen, die rechteste (LSB) Stelle hat die Wertigkeit 1 (2 hoch 0), die linkeste (MSB) 127 (2 hoch 7), somit ist der Dezimalwert: 1 * 127 + 1 * 1 = 128 (Dezimal)
- Hexadezimal-System (Basis 16)
- Jede Stelle kann 16 Werte annehmen: 0 bis F (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A, B, C, D, E, F) (wobei Ah=10d, Bh=11d, Ch=12d, Dh=13d, Eh=14d, Fh=15d)
- Beispiel 1: Die Zahl 10 (NICHT Zehn) hat 2 Stellen, die rechteste (LSB) Stelle hat die Wertigkeit 1 (16 hoch 0), die linkeste (MSB) 16 (16 hoch 1), somit ist der Dezimalwert: 1 * 16 + 0 * 1 = 16 (dezimal)
- Beispiel 2: Die Zahl 0F ist: 0 * 16 + 15 * 1 = 15 (dezimal)
- Beispiel 3: Die Zahl FF ist: 15 * 16 + 16 * 15 = 255 (dezimal)
- Dezimal-System (Basis 10)
Nun mal Dezimal, Binär und Hex praktisch:
var a: byte; a:=128; // Entspricht 10000000b oder 80h ($80) a:=255; // Entspricht 11111111b oder FFh ($FF)
a:=$FF; // Entspricht 11111111b oder 255 a:=$10; // Entspricht 00010000b oder 16
Über TColors (TColor ist nichts anderes wie ein Integer, darin sind die Bits so aufgeteilt:)
var farbe: TColor; farbe:=clWhite; // Die Bits sind: 0 0 0 0 0 0 0 0 | 1 1 1 1 1 1 1 1 | 1 1 1 1 1 1 1 1 | 1 1 1 1 1 1 1 1
Bit-Shifts
- SHL verschiebt die Bits eines Bytes oder Integers nach links
- Beispiele:
var a, b: integer;
a:=1; // a ist: 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 1 b:=a shl 8; // b ist: 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 0 0 // (Alle Bits wurden um 8 Stellen nach links verschoben; b ist also 256)
a:=65.536; // a ist: 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 1 b:=a shl 16; // b ist: 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 // (Alle Bits wurden um 16 Stellen nach links verschoben, das rote wurde ins Nirvana verschoben, // das grüne landete tats. 16 Stellen weiter links; b ist also 65.535
- SHR verschiebt die Bits eines Bytes oder Integers nach rechts
- Beispiele:
var a, b: integer;
a:=65.536; // a ist: 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 1 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 1 b:=a shr 16; // b ist: 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 1 // (Alle Bits wurden um 16 Stellen nach rechts verschoben; b ist also 1; // das grüne Bit ist leider rechts runtergefallen)
Bitmasken mit and und or
- Boolsche Algebra kurz erklärt:
- AND - bei einem AND ist das Ergebnis nur 1, wenn beide Bits 1 sind, Beispiele:
- 1 AND 1 = 1
- 1 AND 0 = 0
- 0 AND 1 = 0
- 0 AND 0 = 0
- OR - bei einem OR ist das Ergebnis 1, sofern mindestens ein Bit 1 ist, Beispiele:
- 1 OR 1 = 1
- 1 OR 0 = 1
- 0 OR 1 = 1
- 0 OR 0 = 0
- NOT - kehrt den Wert um:
- not 0 = 1
- not 1 = 0
(XOR, NAND etc. lassen wir mal weg :) )
- AND - bei einem AND ist das Ergebnis nur 1, wenn beide Bits 1 sind, Beispiele:
- Anwendung als Bitmaske, um z.B. eine Farbe aus einem TColor zu isolieren:
var farbe: TColor; gruen: byte;
gruen:=farbe shr 8; // Verschiebt die Bits um 8 Stellen nach rechts, // damit landet das Grün-Byte im rechtesten Byte des Integers (war vorher das Rot-Byte) gruen:=gruen AND $FF; // Lässt nur noch die rechtesten 8 Bits stehen, // die linken (Grün & Blau) werden "ausmaskiert" und sind 0
- Links:
- Integer und andere ordinale Typen in FreePascal (=Lazarus=Delphi): http://www.freepascal.org/docs-html/ref/refsu5.html
- Integer in Wikipedia: http://de.wikipedia.org/wiki/Integer_(Datentyp)
- Fußnoten: