Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Bits auslesen? (https://www.delphipraxis.net/124478-bits-auslesen.html)

Z4ppy 19. Nov 2008 17:30


Bits auslesen?
 
Ich will aus einem Daten-Byte (das aus einem String oder einem Stream stammt) die einzelnen Bits auslesen. Danach möchte ich mit ihnen weiterrechnen ;) Nun hab ich dazu aber einige Fragen :D

1. Wie les ich die Bits aus? Ich hab zwar dieses Thema gefunden, aber das hat mir nicht sonderlich weitergeholfen :oops:
2. Wie speicher ich die Bits am besten ab? Ich benötige sämtliche 8 Bits (getrennt), da ich mit ihnen unterschiedlich weiterrechnen will...
Weitere Fragen folgen evtl. :D

MfG Z4ppy

PS.: Bitte fragt jetzt nicht nach, was ich am Schluss machen will ;) Auf jeden Fall brauch ich für mein Projekt die einzelnen Bits - basta!

DeddyH 19. Nov 2008 17:34

Re: Bits auslesen?
 
Tut mir Leid, dass Du mein Tut nicht verstanden hast. Aber was genau meinst Du mit "Bits auslesen"? Willst Du gezielt nachsehen, ob ein bestimmtes Bit gesetzt ist? Das geht mit dem "bitweisen und", in Delphi also AND.
Beispiel:
Delphi-Quellcode:
if (Zahl and 16) = 16 then //Bit ist gesetzt

SirThornberry 19. Nov 2008 17:36

Re: Bits auslesen?
 
Die Frage die sich mir stellt ist, ob es etwas bringt die einen Quelltext zu zeigen der bits setzt und ausliest. Oder ist es besser dir die Bitoperatoren zu erklären damit du auch verstehst wie das ganze funktioniert.
Weißt du Beispielsweise welche Bits bei der Zahl 182 gesetzt sind (bzw. wie man das durch rechnen heraus findet)? Also weißt du generell wie sich der Wert eines Byte aus den einzelnen Bits zusammensetzt und welche Wertigkeit dabei die entsprechenden bits haben? Und weißt du in diesem Zusammenhang warum in 1 Byte nur eine Zahl bis maximal 255 passt (unsigned)?
All das wäre interessant um zu wissen ab wo es sinnvoll ist anfzufangen mit der Erklärung :-)

Z4ppy 19. Nov 2008 17:47

Re: Bits auslesen?
 
@Deddy:Ja genau, ich will im Prinzip wissen, ob ein Bit eine 0 oder eine 1 enthält, bzw. welche Bits gesetzt sind ;)
Für das hinterste Bit könnte man auch den Code nehmen, oder? (Wenn ja, dann hab ich dein Tut ja doch verstanden :D)
Delphi-Quellcode:
if(Zahl and (1 shl 0)=(1 shl 0)) then //hinterstes bit gesetzt
Dann könnte man das nämlich durch ne schöne Schleife sausen lassen und hätte gleich alle Bits :D

@SirThornberry: Ja, ich weiss, was die einzelnen Bit-Operationen (or, and, xor) machen und ich kenne auch die Wertigkeit der einzelnen Bits ;)
182 müsste etwa dem Bit 10110110 entsprechen, oder? (also 128 + 32 + 16 + 4 + 2)

MfG Z4ppy

DeddyH 19. Nov 2008 17:51

Re: Bits auslesen?
 
Damit hast Du doch im Prinzip Deinen Lösungsweg ;)

Z4ppy 19. Nov 2008 17:54

Re: Bits auslesen?
 
Danke für deine Hilfe :thumb: Dann hab ich ja doch noch was von deinem Tut verstanden :lol:

MfG Z4ppy

SirThornberry 19. Nov 2008 19:19

Re: Bits auslesen?
 
wenn man immer nur eine 1 shiftet und diese mit einem logischen und verknüpft reicht es auf ungleich 0 zu prüfen. Denn entweder dieses 1 bit ist gesetzt oder keines (denn die 1 ist ein einzelnes bit und wenn man dieses shiftet bleibt auch weiterhin nur 1 bit gesetzt welches dann entweder gesetzt ist (ungleich 0) oder eben nicht gesetzt ist (gleich 0)).

DeddyH 19. Nov 2008 19:24

Re: Bits auslesen?
 
Es spricht aber auch nichts dagegen, gegen Konstanten zu prüfen.

nicodex 20. Nov 2008 08:10

Re: Bits auslesen?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Da ich sowas öfter brauche (Datenanalyse), habe ich mir inzwischen Hilfstypen und -funktionen geschrieben, um die Arbeit mit Sets/Bits/Flags zu vereinfachen (und den Quelltext lesbarer zu halten). Anbei eine Unit für Delphi und FreePascal.

Richtig angenehm wird die Verwendung der TSetX-KlassenStrukturen erst ab BDS2006 (Funktionen und Operatoren für Strukturen). Für ältere Delphi-Version bleibt nur TSetX_Get/SetBit (bei Delphi-Versionen die "inline" unterstützen, gibt’s trotz Lesbarkeit kaum Performancenachteile).

alzaimar 20. Nov 2008 08:43

Re: Bits auslesen?
 
Nicht schlecht, aber ein wenig viel Code, finde ich.
Ich prüfe Bits so:
Delphi-Quellcode:
Const
  ccMyBit7Status = $0070;
  ccMyBit34Status = $0018;

...
Begin
  If FullStatusWord and ccMyBit7Status <> 0 then .... // Bit 7 gesetzt
  If FullStatusWord and ccMyBit34Status <> 0 Then .... // Bit 3 oder 4 gesetzt
  If FullStatusWord and ccMyBit34Status = ccMyBit34Status Then .... // Bit 3 und 4 gesetzt

//  Oder so
  If FullStatusWord and (1 shl 7) <> 0 then ...
...
Wenn Du Dir den VCL-Quellcode anschaust, wird das auch eigentlich immer so gemacht: Man definiert sich seine Bitkonstanten so, das sie schön leserlich sind (ich packe immer ein 'cc' vor so eine Konstante, frag mich nicht wieso) und prüft dann über eine Maskierung.

Wenn man unbedingt will, kann man die Abfrage bzw. das Setzen noch in Routinen packen und so kapseln, oder gleich eine Klasse draus basteln und die Methoden als Class Function (bzw. Procedure) deklarieren.

Ich sehe aber nicht so viel Sinn darin, eine einfache Maskierung und abfrage noch zu kapseln.

nicodex 20. Nov 2008 08:53

Re: Bits auslesen?
 
Ich muss öfter mit schlecht oder gar nicht dokumentierten Datenblöcken arbeiten. Da ist es dann mit einer aktuellen Delphi-Version einfacher die Strukturmitgleider gleich als TSetX zu definieren und mittels Bit[x]-Property darauf zuzugreifen (solange bis die Bedeutung feststeht und/oder ich einen eigenen Typen dafür deklariere). Zumal Sets die Arbeit mit mehren Bits bzw. Masken vereinfachen können. Die generischen Hilfsfunktionen und -typen sind ja auch nicht die Lösung für alle Probleme :)

ps: Die Menge des Quellcodes für die Hilfstypen ist mir egal (einmalige Aktion), solange es mir die Arbeit mit den Daten vereinfacht.

alzaimar 20. Nov 2008 08:56

Re: Bits auslesen?
 
Na klar.

Luckie 20. Nov 2008 08:59

Re: Bits auslesen?
 
Ich habe mir mal erlaubt die Unit bei mir zu Hosten: http://www.michael-puff.de/Developer.../Importe/Nico/ sonst ist sie wieder verschwunden.

nicodex 20. Nov 2008 09:00

Re: Bits auslesen?
 
Zitat:

Zitat von alzaimar
Bis sich die Implementierung der Sets ändert...

Theoretisch, ja. Aber dann kann ich auch gleich den Compiler wechseln ;)
Sollte dieser Umstand eintreten (meiner Meinung nach nicht zu erwarten), dann portiert man halt die Hilfstypen und -funktionen...

Zitat:

Zitat von Luckie
Ich habe mir mal erlaubt die Unit bei mir zu Hosten: http://www.michael-puff.de/Developer.../Importe/Nico/ sonst ist sie wieder verschwunden.

Danke, aber die Unit ist Teil von http://www.bendlins.de/nico/delphi/NcxWOW64.zip

Luckie 20. Nov 2008 09:04

Re: Bits auslesen?
 
Ist jetzt auch bei mir gelandet. ;)

Z4ppy 21. Nov 2008 23:47

Re: Bits auslesen?
 
So, nochmal :lol:
Hab nämlich ein seltsames Problem. Ich hab nun eine Procedur GetBits, der übergebe ich das Byte X und das array, in das sie die Bits schreiben soll (als integer)...

Delphi-Quellcode:
procedure GetBits(X:Byte;Target:array of integer);
var i:integer;
begin
  for i:=0 to 7 do
    if(X and (1 shl i))=(1 shl i) then Target[7-i]:=1
    else Target[7-i]:=0;
end;
Dann ruf ich das so auf:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var tmp:Array[0..7]of integer;
    i:integer;
begin
  GetBits(ord(Edit1.Text[1]),tmp);
  Edit2.Text:='ord: '+inttostr(ord(Edit1.Text[1]))+' | Bit: ';
  for i:=0 to 7 do Edit2.Text:=Edit2.Text+inttostr(tmp[i]);
end;
Das gibt aber das hier:
Code:
ord: 97 | Bit: 43214167772161242548211761055642072234358324
:wall: :wall: :wall:

Wenn ich mal nach jeder einzelnen Integer leerschläge einfüge, sieht das so aus:
Code:
ord: 97 | Bit: 43 2 14 16777216 1242548 2117610556 4207223 4358324
Abgesehen davon, dass die 6. Zahl an der oberen Grenze von Integer kratzt, ist das natürlich völlig normal und genau das, was ich wollte :roll:

Nun, zum Test hab ich dann mal das gemacht:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var tmp:Array[0..7]of integer;
    i:integer;
begin
  for i:=0 to 7 do
    if(ord(Edit1.Text[1]) and (1 shl i))=(1 shl i) then tmp[7-i]:=1
    else tmp[7-i]:=0;
  Edit2.Text:='ord: '+inttostr(ord(Edit1.Text[1]))+' | Bit: ';
  for i:=0 to 7 do Edit2.Text:=Edit2.Text+inttostr(tmp[i]);
end;
Und siehe da, es kommt das Richtige raus:
Code:
ord: 97 | Bit: 01100001
Kann mir das jemand erklären? :? Der Code zum Auslesen der Bits ist ja absolut identisch...

MfG Z4ppy

€dit: So, nochmal Direktvergleich, dann wirds nämlich noch seltsamer :?
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var tmp,tmp2:Array[0..7]of integer;
    i:integer;
begin
  for i:=0 to 7 do
    if(ord(Edit1.Text[1]) and (1 shl i))=(1 shl i) then tmp[7-i]:=1
    else tmp[7-i]:=0;
  Edit2.Text:='ord: '+inttostr(ord(Edit1.Text[1]))+' | Bit: ';
  for i:=0 to 7 do Edit2.Text:=Edit2.Text+inttostr(tmp[i]);

  GetBits(ord(Edit1.Text[1]),tmp2);
  Edit3.Text:='ord: '+inttostr(ord(Edit1.Text[1]))+' | Bit: ';
  for i:=0 to 7 do Edit3.Text:=Edit3.Text+inttostr(tmp2[i]);
end;
Inhalt Edit2:
Code:
ord: 97 | Bit: 01100001
Inhalt Edit3:
Code:
ord: 97 | Bit: 00000000
:wiejetzt:

Hawkeye219 22. Nov 2008 00:00

Re: Bits auslesen?
 
Hallo,

wenn du Werte empfangen möchtest, dann musst du das dem Compiler auch sagen:

Delphi-Quellcode:
//procedure GetBits(X:Byte;Target:array of integer);
procedure GetBits(X:Byte;var Target:array of integer);
Gruß Hawkeye

Z4ppy 22. Nov 2008 00:03

Re: Bits auslesen?
 
:wall:
War ja klar, dass das sowas is :roll: Ich glaub, ich sollte mal bissl mehr schlafen :lol:

Danke dir :thumb:

MfG Z4ppy


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:42 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz