Bitmanipulation für Anfänger: Difference between revisions
Jump to navigation
Jump to search
(19 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
Wer MBI in [[Bielefeld]] bei [http://www.fh-bielefeld.de/fb3/kettner Prof. Dr. rer. nat. K.-U. Kettner] studiert, braucht bestimmt dieses Wissen<ref>...obwohl es red(), green() und blue() gibt :)</ref>: | |||
=== Von Bits und Bytes === | === Von Bits und Bytes === | ||
==== Daten-Typen (Variablen-Typen) ==== | ==== Daten-Typen (Variablen-Typen) ==== | ||
Line 7: | Line 9: | ||
* 1 ''Byte''... | * 1 ''Byte''... | ||
** ...hat 8 Bit | ** ...hat 8 Bit | ||
** ein Byte kann 256 (2 hoch | ** ein Byte kann 256 (2 hoch 8) Werte annehmen: 0 bis 255 | ||
** Beispiel: <tt>0 0 0 0 0 0 0 0</tt> ist der Wert 0 | ** Beispiel: <tt>0 0 0 0 0 0 0 0</tt> ist der Wert 0 | ||
** Beispiel: <tt>1 0 0 0 0 0 0 0</tt> ist der Wert 128 | ** Beispiel: <tt>1 0 0 0 0 0 0 0</tt> ist der Wert 128 | ||
Line 14: | Line 16: | ||
* 1 ''Integer''<ref>wir meinen Signed-32-Bit Integer, 8-, 16- und 64-Bit-Integer und unsigned lassen wir mal weg :)</ref> | * 1 ''Integer''<ref>wir meinen Signed-32-Bit Integer, 8-, 16- und 64-Bit-Integer und unsigned lassen wir mal weg :)</ref> | ||
** hat 4 Byte (32 Bit) | ** hat 4 Byte (32 Bit) | ||
** kann 4.294.967.296 Werte annehmen: −2.147.483.648 bis 2.147.483.647 | ** kann 4.294.967.296 (2 hoch 32) Werte annehmen: −2.147.483.648 bis 2.147.483.647 | ||
** Beispiele | ** Beispiele | ||
*** <tt>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</tt> ist der Wert 0 | *** <tt>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</tt> ist der Wert 0 | ||
Line 28: | Line 30: | ||
* Das linkeste Bit eines Bytes oder Integers nennt man das ''Most''SignificantBit<ref>auch MSB genannt</ref>. | * Das linkeste Bit eines Bytes oder Integers nennt man das ''Most''SignificantBit<ref>auch MSB genannt</ref>. | ||
* Die Wertigkeit der Bit wird genau wie im Dezimal-System vergeben (Basis hoch Stelle)... | * Die Wertigkeit der Bit wird genau wie im Dezimal-System vergeben (Basis hoch Stelle)... | ||
** Dezimal-System | ** Dezimal-System (Basis 10) | ||
*** Beispiel 1: Die Zahl <tt>1111</tt>, also Eintausendeinhundertelf hat 4 Stellen, die rechteste (LSB) Stelle hat | *** Jede Stelle kann 10 Werte annehmen: 0 bis 9 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9) | ||
*** Beispiel 1: Die Zahl <tt>1111</tt>, 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 <tt>1211</tt>, also Eintausendzweihundertelf hat den Dezimalwert: 1 * 1000 + 2 * 100 + 1 * 10 + 1 * 1 = 1211<br>Das alles lässt sich genauso auch auf das Binärsystem anwenden: | *** Beispiel 2: Die Zahl <tt>1211</tt>, also Eintausendzweihundertelf hat den Dezimalwert: 1 * 1000 + 2 * 100 + 1 * 10 + 1 * 1 = 1211<br>Das alles lässt sich genauso auch auf das Binärsystem anwenden: | ||
** Binär-System | ** Binär-System (Basis 2) | ||
*** Beispiel 1: Die Zahl <tt>1111</tt>, also (NICHT Eintausendeinhundertelf) hat 4 Stellen, die rechteste (LSB) Stelle hat | *** Jede Stelle kann 2 Werte annehmen: 0 bis 1 (0, 1) | ||
*** Beispiel 2: Die Zahl <tt>10000001</tt>, hat 8 Stellen, die rechteste (LSB) Stelle hat | *** Beispiel 1: Die Zahl <tt>1111</tt>, 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 <tt>10000001</tt>, 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 <tt>10</tt> (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 <tt>0F</tt> ist: 0 * 16 + 15 * 1 = 15 (dezimal) | |||
*** Beispiel 3: Die Zahl <tt>FF</tt> ist: 15 * 16 + 16 * 15 = 255 (dezimal) | |||
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 | <font color='blue'>1 1 1 1 1 1 1 1</font> | <font color='green'>1 1 1 1 1 1 1 1</font> | <font color='red'>1 1 1 1 1 1 1 1</font> | |||
==== Bit-Shifts ==== | ==== Bit-Shifts ==== | ||
Line 40: | Line 62: | ||
var a, b: integer; | 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 <font color=' | 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 <font color='red'>1</font> | ||
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 <font color=' | 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 <font color='red'>1</font> | 0 0 0 0 0 0 0 0 | ||
// (Alle Bits wurden um 8 Stellen nach links verschoben; b ist also 256) | // (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 <font color=' | a:=65.536; // a ist: 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 <font color='blue'>1</font> | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 <font color='red'>1</font> | ||
b:=a shl 16; // b ist: 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 <font color=' | b:=a shl 16; // b ist: 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 <font color='red'>1</font> | 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, | // (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 | // das grüne landete tats. 16 Stellen weiter links; b ist also 65.535 | ||
Line 52: | Line 74: | ||
var a, b: integer; | var a, b: integer; | ||
a:=65.536; // a ist: 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 <font color=' | a:=65.536; // a ist: 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 <font color='blue'>1</font> | 0 0 0 0 0 0 0 0 | 0 0 0 0 0 0 0 <font color='red'>1</font> | ||
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 <font color=' | 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 <font color='blue'>1</font> | ||
// (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'' ==== | ==== 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<br>(XOR, NAND etc. lassen wir mal weg :) ) | |||
* 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 | |||
---- | ---- |
Latest revision as of 19:25, 9 June 2013
Wer MBI in Bielefeld bei Prof. Dr. rer. nat. K.-U. Kettner studiert, braucht bestimmt dieses Wissen[1]:
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: