Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Bits und Bytes


BL - So 30.10.11 17:38
Titel: Bits und Bytes
Hallo,


man möge folgende Anfängerfrage verzeihen, aber wie greife ich denn in Deplhi auf die einzelnen Bits von Integer, bzw. Byte-Variablen zu?

Zum Hintergrund: Ich sitze an einem Projekt, in dem eine Delphi-Software über eine virtuelle COM-Schnittstelle via USB auf einen Microcontroller zugreift. Da werden dann beispielsweise Einstell-Daten ausgelesen, verändert und wieder reingespielt. Dazu muß ich aber auf die einzelnen Bit in ganz bestimmten Bytes zugreifen können und ich weiß nicht (mehr) wie das unter Delphi war.
Die anderen Geschichten wie die Umwandlungen Hex-String als 2 ASCII-Zeeichen nach Byte/Integer und zurück usw. habe ich. Nur die einzlenen Bits fehlen mir.


BL


Martok - So 30.10.11 18:28

Üblicherweise über bitweise Arithmetik, du verrechnest also einen Wert mit Bitmasken.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
//Bit 2 (Wert 4) setzen:
neu:= alt or $00000004;

//Bit 2 entfernen:
neu:= alt and not $00000004;

//Ist bit 3 gesetzt?
if (neu and $0000008)>0 then
  //...


€: Warum das so ist, erklärt Nersgatt unter mir ;)

[meta]Bitweiser Zugriff[/meta]


Nersgatt - So 30.10.11 18:30

Sowas kannst Du mit Boolscher Verknüpfung machen.

Stell Dir vor, Du hat ein Byte mit folgendem Inhalt:
10001000
Jetzt möchtest Du z.B. sicherstellen, dass das 3. Bit gesetzt ist (wenn es nicht gesetzt ist, soll es gesetzt werden, wenn es schon gesetzt ist, soll es so bleiben). Dafür verknüpfst Du Dein Byte einfach mit folgender Zahl:
00100000
Hierbei spricht man von "Maske".

Es ergibt sich also:

Quelltext
1:
2:
3:
4:
   10001000
OR 00100000
   --------
   10100000


Abfragen, ob das Bit gesetzt ist, kann man mit AND:

Quelltext
1:
2:
3:
4:
    10001000
AND 00100000
    --------
    00000000

Ergebnis = 0, Bit nicht gesetzt


Quelltext
1:
2:
3:
4:
    10101000
AND 00100000
    --------
    00100000

Ergebnis <> 0, Bit ist also gesetzt.


rushifell - So 30.10.11 21:51

Wobei die Zählung der einzelnen Bits üblicherweise von 0 bis 7 geht. Meist geht die Zählung von rechts (0) nach links (7). Wenn das Bit an Position 0 (das niedrigstwertigste Bit lsb) gesetzt ist, also 00000001 = 1 (Dezimal), wenn das Bit an Position 7 (das höchstwertigste Bit msb) gesetzt ist, also 10000000 = 128 (Dezimal)

lsb = least significant bit (Kleinschreibung)
msb = most significant bit (Kleinschreibung)

Bei Großschreibung (LSB, MSB) geht es üblicherweise um die Byte-Reihenfolge.

Achtung, die Zählung kann auch von links beginnen! Um Irrtümer auszuschließen, sollte das angegeben werden.

Hier noch eine Möglichkeit herauszufinden, ob ein Bit gesetzt ist:

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
Var b,
    position:Byte;
begin
b:=0;
IF (b SHR Position) AND 1 <> 0 then ShowMessage('Bit gesetzt');
//Ergebnis = 1; Bit gesetzt, Ergebnis = 0; Bit nicht gesetzt
end.

... und eine Möglichkeit ein Bit zu setzen

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
Var b,
    position:Byte;
begin
b:=0;
b := b OR (1 shl Position);
end.


Gruß


BL - Mo 31.10.11 13:25

Besten Dank, klappt einwandfrei.



BL


Tranx - Mo 31.10.11 13:52

Nur eine kleine Korrektur:

Es ergibt sich also:

Quelltext
1:
2:
3:
4:
   10001000
OR 00100000
   --------
   10101000


und zur Vervollständigung:


Quelltext
1:
2:
3:
4:
    10001000
XOR 00100000
    --------
    10101000


in dem Falle identisch mit OR, aber siehe folgendes Beispiel:


Quelltext
1:
2:
3:
4:
    10001000
XOR 11111111
    --------
    01110111

= Umkehrung der Bits durch xor-Verknüpfung. Kann u.a. auch bei Codierung-Decodierung Anwendugn finden.

A xor B => C; C xor B => A

und dann noch not als unärer Operator:


Quelltext
1:
    not 10001000 = 011101111                    


ist identisch mit dem o.a. XOR-Code. Allerdings ist zu beachten, dass die Bitgröße der Variablen zu berücksichtigen sind. Bei 8 bit gilt das o.a., bei 16 bit wird z. b. aus


Quelltext
1:
    not 0000000000001000 = 1111111111110111                    


dito gilt ähnliches für 32-bit und 64-bit Zahlen