Entwickler-Ecke

Delphi Language (Object-Pascal) / CLX - Funktion zum Auslesen von Bit-Besetzung


Unzi - Do 19.06.03 15:12
Titel: Funktion zum Auslesen von Bit-Besetzung
Hallo,

ich wollte mal fragen, ob jemand eine Funktion kennt, mit der man bei einer Variable vom Typ Byte prüfen kann, welche der einzelnen Bits gesetzt sind?

Danke im voraus!

Unzi


tommie-lie - Do 19.06.03 15:32

Eine fertige Funktion gibt es AFAIK nicht, aber mit dem boolschen Vergleich and kannst du sowas machen.

Delphi-Quelltext
1:
2:
3:
4:
Wert and 1 = 1
Wert and 2 = 2
Wert and 4 = 4
// usw

Wenn du diese Ausdrücke in if-Abfragen einbaust, prüfst du mit dem ersten das erste Bit, dem zweiten das zweite Bit usw.
Also jeweils den Bit-Wert einsetzen. Dieser ist 2^x, wobei x das xte Bit ist.


Tweafis - Do 19.06.03 15:55

Oder Als Funktion (hatten wir doch erst kürzlich)


Delphi-Quelltext
1:
2:
3:
4:
5:
function BitGesetzt(Wert, Bit: Byte):Boolean;
begin
  result := false;
  if Wert and Bit = Bit then result := true;
end;


Motzi - Do 19.06.03 17:17

Und schau dir mal die beiden Schiebe-Operatoren shl und shr in der OH an...


tommie-lie - Do 19.06.03 17:44

Ähh, Twaefis, was denkst du, soll man dort als Parameter "Bit" angeben?
Alles, aber garantiert nicht das bit ;-)
Wenn, dann richtig: ;-)

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
function BitGesetzt(Wert, Bit: Byte):Boolean;
begin
  result := false;
  if (Wert shr Bit - 1and 1 = 1 then
    result := true;
end;


P.S.: Hier werden die Bits nicht von 0 an gezählt. Der erste Bit ist also wirklich 1, das zweite 2 usw.
Lässt man das " - 1" weg, wäre das erste Bit 0, das zweite 1 usw.


DaFox - Do 19.06.03 23:49

tommie-lie hat folgendes geschrieben:

P.S.: Hier werden die Bits nicht von 0 an gezählt.


Das ist mathematisch auch korrekt, da 2^0 = 1. In der Informatik/Mathematik sehen Binärzahlen immer so aus: <a> = a_(n-1)...a_0.

Gruß,
Markus


Unzi - Fr 20.06.03 16:39

Danke euch allen für die wertvollen Tipps. Ich denke, ich kann sie sehr gut gebrauchen.

Gruß!
Unzi


tommie-lie - Fr 20.06.03 17:15

DaFox hat folgendes geschrieben:
tommie-lie hat folgendes geschrieben:

P.S.: Hier werden die Bits nicht von 0 an gezählt.
Das ist mathematisch auch korrekt, da 2^0 = 1. In der Informatik/Mathematik sehen Binärzahlen immer so aus: <a> = a_(n-1)...a_0.

Eben deswegen ist es ja falsch ;-)
Man gibt meiner Prozedur das Bit an, beginnt aber bei eins. Meine "Bits" gehen für ein Byte von 1 bis 8, nicht von 0 bis 7.
Wenn man das "- 1" entfernt, ist es aber wieder mathemtaisch korrekt.


Unzi - Fr 20.06.03 17:39

Du hast Recht. Ich habs mal ausprobiert, aber so richtig spitze gings nicht, wahrscheinlich lag es daran. Ich habe es dann einfach so gemacht:


Quelltext
1:
2:
3:
byte_var:=byte_var or 1;
oder
byte_var:=byte_var or 2;


usw.

und dann:


Quelltext
1:
if byte_var=byte_var or 1 then ...                    


usw.

Trotzdem vielen Dank für die Mühe!

Unzi


tommie-lie - Fr 20.06.03 18:15

Mit or?
Und du bist sicher, daß das klappt?
Bsp:
 100101 or 4 = 100101 :roll:

Meine Funktion dürfte da wohl die Geeignetere sein ;-)
Aber du musst wirklich die Bitstellen angeben. Nicht 1, 2, 4, 8, 16 ... 128, sondern 1, 2, 3, 4, 5, 6, 7 und 8 (bei einem Byte).


Unzi - Sa 21.06.03 10:59

Also, die or-Methode hat wunderbar funktioniert, und das reicht mir eigentlich. Außerdem sind bei den Flag-Variablen ja auch immer oder-Kombinationen im Spiel. Außerdem habe ich schon verstanden wie man so eine Funktion benutzt.

Unzi


Tweafis - Sa 21.06.03 11:34

tommie-lie hat folgendes geschrieben:
Ähh, Twaefis, was denkst du, soll man dort als Parameter "Bit" angeben?
Alles, aber garantiert nicht das bit ;-)
Wenn, dann richtig: ;-)

Delphi-Quelltext
1:
2:
3:
4:
5:
6:
function BitGesetzt(Wert, Bit: Byte):Boolean;
begin
  result := false;
  if (Wert shr Bit - 1and 1 = 1 then
    result := true;
end;


P.S.: Hier werden die Bits nicht von 0 an gezählt. Der erste Bit ist also wirklich 1, das zweite 2 usw.
Lässt man das " - 1" weg, wäre das erste Bit 0, das zweite 1 usw.


Dachte nur weil man mit

Wert and 1 = 1 machen kann. :(
vielleicht so


Delphi-Quelltext
1:
if (Wert and Bit) = Bit then result = true;                    


???


Wolff68 - So 22.06.03 14:51

Ich hab mal 2 Funktionen ausgekramt.
Die Erste ist eine Umwandlung von Byte zu Binär-String.
Die zweite vergleicht einen Byte-Wert mit einer binären Maske, wobei auch Joker erlaubt sind.
Ist ganz nützlich, wenn man auch binäre Kombinationen abfragen will.

Bei Bedarf kann man es auch leicht abwandeln, um Variablen der Typen Word(16) oder LongWord(32) abzufragen.


Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
function IntToBin(iSrc: Byte): String;
{ Umwandlung Byte in String mit Binärwert }
var
  i : Integer;
begin
  Result := '';
  For i := 1 to 8 do begin
    Result := IntToStr(iSrc AND 1) + Result;
    iSrc := iSrc shr 1;
  end;
end;

function BitVergleich(sMask: String; iSrc: Byte): Boolean;
{ Vergleicht Binär mit Maske. Alles ausser '0' und '1' sind Joker }
var
  i : Integer;
  sSrc : String[8];
begin
  sSrc := IntToBin(iSrc);
  While Length(sMask) < 8 do sMask := '*' + sMask; // Maske auf 8 Zeichen erweitern
  Result := true;
  For i := 1 to 8 do begin
    IF (sMask[i] in ['0','1']) AND (sSrc[i] <> sMask[i]) then Result := false;
  end;
end;


tommie-lie - So 22.06.03 14:59

Tweafis hat folgendes geschrieben:
Dachte nur weil man mit

Wert and 1 = 1 machen kann. :(
vielleicht so


Delphi-Quelltext
1:
if (Wert and Bit) = Bit then result = true;                    


???

Da gibst du aber nicht das Bit an, sondern dessen Wert ;-)
Um das zweite Bit zu vergleichen kannst du noch "and 2" benutzen, aber das dritte fällt mit 4 aus der Reihe, danach ebenfalls.
Ich shifte den ganzen Integer um x stellen und prüfe so tatsächlich auf dsa bit, nicht auf dessen Wert.


Tweafis - So 22.06.03 15:46

Naja, ich hab das halt so gemacht das es

1 2 4 8 16 32 usw. angeben muss.

(Absicht :mrgreen: ;))