Bits testen

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Antworten
chickendev
Beiträge: 37
Registriert: Do 23. Feb 2012, 03:41

Bits testen

Beitrag von chickendev »

Ich wollte mal fragen wie man mit Pascal einzelne Bits von einem Byte testen kann?

Also ich habe z.B. einen Byte mit dem Wert 137, wie kann ich testen welche Bits der 8 Stellen des Bytes gesetzt sind, also z.B. 01001001.

Und umgekehrt, wie kann ich eine Bitfolge in einen Intwert umrechnen?

MAC
Beiträge: 770
Registriert: Sa 21. Feb 2009, 13:46
OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
CPU-Target: 32Bit

Re: Bits testen

Beitrag von MAC »

ich glaube dafür gibt es die funktion "shl". Wie man die genau anwendet weis ich komischerweise nicht, da ich nie bitweise arbeite :D Aber sicherlich kennen eine menge Leute hier ein kleinen Beispiel oder du suchst einfach mal auf Google "shl delphi"

Code: Alles auswählen

Signatur := nil;

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Bits testen

Beitrag von mschnell »

Teste Bit n

if (x and (1 shl n)) <> 0 then ....

Wenn Du viele Einzel-Bits verwalten willst nimmst du einen "set" Typ. (Die Binär-Arithmentik ist identisch mit der Mengen-Arithmetik.)

-Michael

chickendev
Beiträge: 37
Registriert: Do 23. Feb 2012, 03:41

Re: Bits testen

Beitrag von chickendev »

Hi, ich habe schon ein wenig herumprobiert, kann das aber nicht wirklich richtig auf meinen Code anwenden.

Was müsste ich bei mir ändern?
Ich dachte erst ich könnte mit XOR alle anderen Bits abziehen und das so testen, klappt aber leider nur wenn alle bis auf Bit X gesetzt sind :?

Code: Alles auswählen

function kanal_test(Kanal : ShortInt) : Boolean;
var
  kanal_status, lpt_status : Integer;
begin
  lpt_status := parport_wert;
 
  if Kanal = 1 then begin
     kanal_status := (lpt_status XOR 254);//bit entfernen = aktivieren
     ShowMessage('XOR ergebnis'+IntToStr(kanal_status));
     if kanal_status = 1 then begin
        Result := False;
        ShowMessage('false');
     end else begin
        Result := True;
        ShowMessage('true');
     end;
  end;
 
end;

chickendev
Beiträge: 37
Registriert: Do 23. Feb 2012, 03:41

Re: Bits testen

Beitrag von chickendev »

mschnell hat geschrieben:Teste Bit n

if (x and (1 shl n)) <> 0 then ....

Wenn Du viele Einzel-Bits verwalten willst nimmst du einen "set" Typ. (Die Binär-Arithmentik ist identisch mit der Mengen-Arithmetik.)

-Michael


Damit ich das richtig verstehe also

Code: Alles auswählen

if (x and (1 shl n)) <> 0 then


würde bedeuten

Code: Alles auswählen

if (MEINE_INT_ZAHL and (BIT_STATUS shl STELLE_DES_BITS)) <> 0 then


Ist das richtig, weil bei mir funktioniert das nicht :-(

Eb
Lazarusforum e. V.
Beiträge: 238
Registriert: Di 5. Feb 2008, 15:32
OS, Lazarus, FPC: Linux Mint - Laz 2.2.0
CPU-Target: 64Bit
Wohnort: Stuttgart

Re: Bits testen

Beitrag von Eb »

Vermutlich willst du ja wissen, welche Pins vom Parallelport Spannung haben und welche nicht.
Hab jetzt keinen Code zur Hand, aber wenn ich mich richtig erinnere ist ein Pin von den vieren, die man auslesen kann, invertiert, liefert also den gegenteiligen Wert. Ich meine dass ich da als ersten Schritt ein XOR gemacht habe um die Invertierung 'zurückzubiegen'.
Eb

chickendev
Beiträge: 37
Registriert: Do 23. Feb 2012, 03:41

Re: Bits testen

Beitrag von chickendev »

Eb hat geschrieben:Vermutlich willst du ja wissen, welche Pins vom Parallelport Spannung haben und welche nicht.
Hab jetzt keinen Code zur Hand, aber wenn ich mich richtig erinnere ist ein Pin von den vieren, die man auslesen kann, invertiert, liefert also den gegenteiligen Wert. Ich meine dass ich da als ersten Schritt ein XOR gemacht habe um die Invertierung 'zurückzubiegen'.
Eb


Das mit dem invertieren ist erstmal egal, ich brauche ja nur 0 oder 1 um danach selbst zu invertieren, ich schlage mich gerade hiermit herum:

http://www.lernnetz-sh.de/kmLinux/doc/P ... as622.html
http://www.functionx.com/objectpascal/Lesson09.htm

Irgendwie will das nicht richtig funktionieren :(

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Bits testen

Beitrag von mschnell »

chickendev hat geschrieben:Teste Bit n würde bedeuten

Code: Alles auswählen

if (MEINE_INT_ZAHL and (BIT_STATUS shl STELLE_DES_BITS)) <> 0 then



Nö !

Der Bitstatus ist das, was beim "If" rauskommt.

Wenn Bitstatus sinnvollerweise ein logischer Wert ist (Boolean) ist also

Bitstatus = (x and (1 shl n)) <> 0;


Wenn Du ein Bit entsprechend Bitstatus setzen willst:

if Bitstatus then x := x or (1 shl n);  else x := x and ( not (1 shl n));

-Michael

chickendev
Beiträge: 37
Registriert: Do 23. Feb 2012, 03:41

Re: Bits testen

Beitrag von chickendev »

Vielen Dank!!!!

Es hat jetzt funktioniert! :)

Hier der Code, für alle die das nicht wissen, die Stelle des Bits ist gleich minus 1. Wollt Ihr Bit 7 abfragen muss n = 6 sein.

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var
  x,n : Integer;
  Bitstatus : Boolean;
begin
     Bitstatus := FALSE;
     n := StrToIntDef(Edit6.Caption,0);
     x := StrToIntDef(Edit1.Caption,0);
 
     Bitstatus := (x and (1 shl n)) <> 0;
 
     if Bitstatus then Edit7.Caption := 'TRUE';
     if Bitstatus = False then Edit7.Caption := 'FALSE';
end;

Maik81ftl
Beiträge: 619
Registriert: Mi 9. Mär 2011, 16:34
OS, Lazarus, FPC: Ubuntu10.04 LTS (L 0.9.31.0 FPC 2.4.4)
CPU-Target: 64Bit
Wohnort: seit 01.06.2011 in Wahlstedt

Re: Bits testen

Beitrag von Maik81ftl »

chickendev hat geschrieben:Vielen Dank!!!!

Es hat jetzt funktioniert! :)

Hier der Code, für alle die das nicht wissen, die Stelle des Bits ist gleich minus 1. Wollt Ihr Bit 7 abfragen muss n = 6 sein.

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var
  x,n : Integer;
  Bitstatus : Boolean;
begin
     Bitstatus := FALSE;
     n := StrToIntDef(Edit6.Caption,0);
     x := StrToIntDef(Edit1.Caption,0);
 
     Bitstatus := (x and (1 shl n)) <> 0;
 
     if Bitstatus then Edit7.Caption := 'TRUE';
     if Bitstatus = False then Edit7.Caption := 'FALSE';
end;


Gegenfrage wenn erlaubt. Wenn ich richtig sehe, braucht du ja nur den Bitstatus für die Endauswertung. wäre es da nicht sinnvoll, wenn die procedure verkürz wird? zugegeben bei Boolischen abfragen schenk ich mir schon die Zuweisung auf True bzw false. :D dafür bin ich zugegeben schreibfaul :D

empfehle dir daher die zeilen, sollte ggf auch 3 Zeilen Code sparen.

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
    var
      x,n : Integer;
    begin
         n := StrToIntDef(Edit6.Caption,0);
         x := StrToIntDef(Edit1.Caption,0);
 
         if (x and (1 shl n)) = 1 then Edit7.Caption := 'TRUE'
         else Edit7.Caption := 'FALSE';
    end;


ist zugegeben nur ein Tipp meiner Seits, kenne ja einige, die das ggf. hassen werden.
Ubuntu 10.04 LTS ist meine Heimat. Lazarus ist meine Sprache :D und der Kreis Segeberg meine LIEBE :D

Benutzeravatar
corpsman
Lazarusforum e. V.
Beiträge: 1498
Registriert: Sa 28. Feb 2009, 08:54
OS, Lazarus, FPC: Linux Mint Mate, Lazarus GIT Head, FPC 3.0
CPU-Target: 64Bit
Wohnort: Stuttgart
Kontaktdaten:

Re: Bits testen

Beitrag von corpsman »

Code: Alles auswählen

if (x and (1 shl n)) = 1 then Edit7.Caption := 'TRUE


Das ist fasch, bzw gillt nur für n = 0

Richtig wäre :

Code: Alles auswählen

if (x and (1 shl n)) = (1 shl n) then Edit7.Caption := 'TRUE
--
Just try it

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Bits testen

Beitrag von mse »

corpsman hat geschrieben:

Code: Alles auswählen

if (x and (1 shl n)) = (1 shl n) then Edit7.Caption := 'TRUE

Oder

Code: Alles auswählen

if (x and (1 shl n)) <> 0 then Edit7.Caption := 'TRUE

Maik81ftl
Beiträge: 619
Registriert: Mi 9. Mär 2011, 16:34
OS, Lazarus, FPC: Ubuntu10.04 LTS (L 0.9.31.0 FPC 2.4.4)
CPU-Target: 64Bit
Wohnort: seit 01.06.2011 in Wahlstedt

Re: Bits testen

Beitrag von Maik81ftl »

corpsman hat geschrieben:

Code: Alles auswählen

if (x and (1 shl n)) = 1 then Edit7.Caption := 'TRUE


Das ist fasch, bzw gillt nur für n = 0

Richtig wäre :

Code: Alles auswählen

if (x and (1 shl n)) = (1 shl n) then Edit7.Caption := 'TRUE


Hmmm da ist das Quasi nur zufall, das Meine Variante geht?

Hier mal ein Codeschnippsel, wie ich diese verwende...

Code: Alles auswählen

procedure TForm2.FormShow(Sender: TObject);
begin
  if (conf and (1 shl 0)) = 1 then
//  if Conf[1] then //SetCom
     begin
       _Text[1]:= TLabel.Create(self);
       with _Text[1] do
         begin
           Parent  := Self;
           Left    := 17;
           Top     := 13;
           Caption := 'Netzwerkname:';
         end;
       Edit[1]:= TEdit.Create(self);
       with Edit[1] do
         begin
           Parent := Self;
           Left   := 17;
           Top    := 32;
         end;
       _Text[2] := TLabel.Create(self);
       with _Text[2] do
         begin
           Parent   := self;
           Left     := 17;
           Top      := 72;
           Hint     := 'z.B. 192.168.1.1';
           Caption  := 'IP-Adresse des Netzwerkes';
           ShowHint :=True;
         end;
       Edit[2] := TEdit.Create(self);
       with Edit[2] do
         begin
           Left    := 17;
           Top     := 96;
         end;
     end
  end;
Ubuntu 10.04 LTS ist meine Heimat. Lazarus ist meine Sprache :D und der Kreis Segeberg meine LIEBE :D

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Bits testen

Beitrag von mse »

Maik81ftl hat geschrieben:Hmmm da ist das Quasi nur zufall, das Meine Variante geht?

Ja. Überlege mal was "1 shl 0" ergibt.

Martin

marcov
Beiträge: 1100
Registriert: Di 5. Aug 2008, 09:37
OS, Lazarus, FPC: Windows ,Linux,FreeBSD,Dos (L trunk FPC trunk)
CPU-Target: 32/64,PPC(+64), ARM
Wohnort: Eindhoven (Niederlande)

Re: Bits testen

Beitrag von marcov »

Code: Alles auswählen

{$mode delphi}
 
type byteset = set of 0..7;
 
const bools : array[false..true] of char = ('0','1');
 
var b : Byte;
    i : integer;
begin
  b:=137;
  for i:=7 downto 0 do
   write(bools[i in byteset(b)]);
  writeln;
end.

Antworten