Entwickler-Ecke
Delphi Language (Object-Pascal) / CLX - Wie function getbits(x:byte): TBitarray realisieren ?
catweasel - Mo 09.02.04 20:36
Titel: Wie function getbits(x:byte): TBitarray realisieren ?
Hi,
ich steh gerade ein bischen auf dem Schlauch. Hab mich mit Bitmanipulation noch nicht so bechäftigt..
Meine Frage ist: Wie kann ich die Bits eines Bytes auslesen...
Ich möchte im Prinzip etwas haben wie:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| var bitarray : array[1..8] of boolean; x : byte;
function getbits(x:byte): array of boolean: var z : integer; begin for z:= low(bitarray) to high(bitarray) do Result[z] := end; |
Ich denke was das werden soll ist klar:
Je nachdem ob das Bit eine 1 oder 0 ist soll das array true oder false enthalten.... Wie mache ich das .. ?
Catweasel
Motzi - Mo 09.02.04 21:07
Ungetestet, aber müsste funktionieren...
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10:
| type TBitArray = array[0..7] of Boolean;
function getbits(x: Byte): TBitArray: var i: Integer; begin for i := Low(Result) to High(Result) do Result[i] := Boolean(x and (1 shl i)); end; |
catweasel - Mo 09.02.04 21:13
| Zitat: |
| Boolean(x and (1 shl i)); |
hm... ich kann irgendwie mit der Funtion boolean() nix anfangen.. Gibts die überhaupt (ich kann die nirgends finden ...) ?
Catweasel...
Anonymous - Mo 09.02.04 21:23
Das ist keine Fkt, sondern ein Typecast von irgendeinem integer nach boolean
catweasel - Mo 09.02.04 21:32
öhmmm :oops: achso ... :)
Motzi - Mo 09.02.04 21:36
| obbschtkuche hat folgendes geschrieben: |
| Das ist keine Fkt, sondern ein Typecast von irgendeinem integer nach boolean |
Ganz genau..!
die Zahl Eins wird um i Stellen nach links geshiftet
x wird mit dem Ergebnis der Shift-Operation and-verknüpft. Ist das Bit gesetzt, dann ist das Ergebnis ein Vielfaches von 2, andernfalls 0
Delphi-Quelltext
1:
| Boolean(x and (1 shl i)) |
Dieser Typecast wandelt das Ergebnis in einen Boolean (True/False) um. Dabei gilt 0=False und als umkehrschluss - alles was ungleich null ist ist dann True..!
catweasel - Mo 09.02.04 23:34
Ah Danke ..!
catweasel - Di 10.02.04 00:34
| Zitat: |
| Boolean(x and (1 shl i)) |
Das das da oben ein Cast ist hab ich nu kapiert... :)
Aber eine Frage noch... : :?:
ich hab noch ein bischen an den Operatoren shl bzw. shr zu kabbern und muss mir das mit den logischen Operatoren nochmal genauer anguggen..
Z.B. Warum gerade die Zahl 1 verschieben.. :?:
@motzi (oder sonst jemand :-) )
Könntest du mir zu lernzwecken auch die Umkehrfunktion kurz erläutern?
Also
Delphi-Quelltext
1:
| function getbyte(bitarray:TBitarray):byte; |
Wäre super.. :-)
Catweasel
Sven - Di 10.02.04 08:10
Nur mal am Rande, in der Unit Classes ist ein Typ deklariert der da heißt TBits. Vielleicht leistet dieser bessere Dienste.
Motzi - Di 10.02.04 14:29
Also shl / shr sind im Prinzip ganz einfach.. sie verschieben die Bits einfach um x Bit nach rechts oder links und füllen die dabei entstehenden Leerräume einfach mit Nullen.
Quelltext
1: 2: 3:
| 00000001 shl 1 -------------- 00000010 |
Quelltext
1: 2: 3:
| 00000001 shl 5 -------------- 00100000 |
Ich verschiebe in dem Code die Zahl 1 weil sie in der Binär-Darstellung nur eine 1 hat und die an erster Stelle ist. Ich shifte dann einfach immer um i Stellen wodurch ich dann immer das nächste Bit gesetzt habe:
Quelltext
1: 2: 3: 4: 5: 6: 7: 8:
| 00000001 shl 0 = 00000001 00000001 shl 1 = 00000010 00000001 shl 2 = 00000100 00000001 shl 3 = 00001000 00000001 shl 4 = 00010000 00000001 shl 5 = 00100000 00000001 shl 6 = 01000000 00000001 shl 7 = 10000000 |
Das wird dann per and verknüpft und das Ergebnis in einen Boolean umgewandelt.
Die Umkerfunktion könnte also ungefähr so ausschauen:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| function GetByte(const aBitArray: TBitArray): Byte; var i: Integer; begin Result := 0; for i := Low(aBitArray) to High(aBitArray) do if aBitArray[i] then Result := Result or (1 shl i); end; |
AndyB - Di 10.02.04 15:55
| Motzi hat folgendes geschrieben: |
Delphi-Quelltext 1:
| Boolean(x and (1 shl i)) |
Dieser Typecast wandelt das Ergebnis in einen Boolean (True/False) um. Dabei gilt 0=False und als umkehrschluss - alles was ungleich null ist ist dann True..! |
Gut beobachtet. Und wenn jetzt jemand kommt, und mit
if BitArray[x] = True then testet, wird er bis auf BitArray[0] immer
False bekommen, weil
True für Boolean als
True = 1 deklariert ist. Da ab (einschließlich) Byte(BitArray[1]) > 1 ist, ergibt eben "x = 1 mit x>1" immer False.
Aus diesem Grund beforzuge ich erstens
und zeitens unterlasse ich Typecasts zu Boolean, wenn das nicht unbedingt nötig ist, indem ich auf ungleich Null prüfe.
Delphi-Quelltext
1:
| Result[i] := x and (1 shl i) <> 0; |
Dadurch übernimmt der Compiler die nötige Umwandlung und macht aus allen Werten ungliech 0 die 1.
Motzi - Di 10.02.04 18:41
| AndyB hat folgendes geschrieben: |
Aus diesem Grund beforzuge ich erstens
|
Tu ich auch (wie man oben sieht)...
| Zitat: |
und zeitens unterlasse ich Typecasts zu Boolean, wenn das nicht unbedingt nötig ist, indem ich auf ungleich Null prüfe.
Delphi-Quelltext 1:
| Result[i] := x and (1 shl i) <> 0; |
Dadurch übernimmt der Compiler die nötige Umwandlung und macht aus allen Werten ungliech 0 die 1. |
Stimmt.. das hab ich nicht beachtet.. dachte bis jetzt es wird jeder Wert <> 0 als True angesehen, dies trifft aber nur bei einer Prüfung ala
zu und nicht bei
Delphi-Quelltext
1:
| if Ausdruck = True then |
da ja ein Boolean im Prinzip eine Menge mit 2 Werten darstellt und Ord(True) = 1 ist...
catweasel - Di 10.02.04 23:30
| Zitat: |
| Nur mal am Rande, in der Unit Classes ist ein Typ deklariert der da heißt TBits. Vielleicht leistet dieser bessere Dienste. |
Naja soo aufregend is der TBits typ ja auch nich... Is ja auch nur ein array of boolean.. gut ok.. es dimensioniert sich selbst.. aber wann hat ein byte schonmal weniger oder mehr als 8 bits ...?
Ich geb zu: für words und doubblewords isses ganz brauchbar, aber für byte reicht auch das eigene Array....
Oder kann TBits noch was geniales das ich übersehen hab ?
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| function GetByte(const aBitArray: TBitArray): Byte; var i: Integer; begin Result := 0; for i := Low(aBitArray) to High(aBitArray) do if aBitArray[i] then Result := Result or (1 shl i); end; |
Da muss ich da auch analog zur getbits funktion auf <> 0 testen, oder?!
| Zitat: |
Gut beobachtet. Und wenn jetzt jemand kommt, und mit
if BitArray[x] = True then
testet, |
Genau das hab ich nämlich beobachtet .. Bit 1 war immer abwechseln false oder true und der rest immr false...
| Zitat: |
| Dadurch übernimmt der Compiler die nötige Umwandlung und macht aus allen Werten ungliech 0 die 1 |
Genau da liegt irgendwie das Problem. Man denkt ein bool wert is true wenn er wahr is und dann ist er auf einmal war wenn er falsch wahr ist .. :shock: Ist das jetzt doppelte Verneinung oder was ? :roll:
Wo liegt genau der Unterschied zwischen:
if Ausdruck then und
if Ausdruck = True then
Und vor allem: Was macht der Compiler da einfach so.. Und warum geht der type cast in diesem Fall schief ?
Catweasel
AndyB - Mi 11.02.04 10:03
| catweasel hat folgendes geschrieben: |
| Da muss ich da auch analog zur getbits funktion auf <> 0 testen, oder?! |
Nein, denn hier interessiert dich ja, welches Bit gesetzt ist.
| Zitat: |
| Und warum geht der type cast in diesem Fall schief ? |
Der Typecast geht hier nicht schief, aber er liefert ein Ergebnis, das man nicht gleich ("=") einem Wert setzen darf.
Ein Beispiel:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| True = 0000 0001 False = 0000 0000
Result := Boolean(1 shl 3) = 0000 1000 if Result = True then = if 0000 1000 = 0000 0001 then FEHLER
Result := Boolean(1 shl 0) = 0000 0001 if Result = True then = if 0000 0001 = 0000 0001 then OK
Result := 1 shl 3 <> 0 = 0000 0001 if Result = True then = if 0000 0001 = 0000 0001 then OK |
| Zitat: |
| Was macht der Compiler da einfach so. |
Er macht aus
Delphi-Quelltext
1:
| Result := 1 shl 3 <> 0; |
grob diesen Code:
Delphi-Quelltext
1:
| if 1 shl 3 <> 0 then Result := True else Result := False; |
Da der Compiler Assembler-Code produziert, kann er das noch ganz schön optimieren, womit es nicht spührbar langsamer als der direkte Typecast läuft.
| Zitat: |
Wo liegt genau der Unterschied zwischen:
if Ausdruck then und if Ausdruck = True |
Bei erstem prüft der Compiler auf "<> 0". Bei zweiten wird direkt mit "= 1" geprüft.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!