array of bits -> byte komische Nebenwirkung

Für Fragen von Einsteigern und Programmieranfängern...
ente
Beiträge: 16
Registriert: Sa 4. Feb 2017, 23:53

array of bits -> byte komische Nebenwirkung

Beitrag von ente »

Hallo,

Ich habe ein Arry of Boolean [1-8] und möchte daraus ein byte machen.
Allerdings bekomme ich statt einer " 1 " eine "-1 ".
könntet ihr mir sagen, was ich falsch mache?

Procedure ...
var i: integer;
begin

for i := 1 to 8 do
begin
Label1.caption := Label1.Caption + BootToStr(ArrayBoolWerte[i]);
end;
end;

Ergebnis mit der Procedure ist grade: 0-1000-1-1-1
Es soll natürlich später kein Label1 sein, das habe ich nur zur Überprüfung genommen. Am Ende soll es ein Hexadezimalwert werden. byte -> Hex kann ich :)

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: array of bits -> byte komische Nebenwirkung

Beitrag von siro »

Hallo ente,
das passiert bei mir auch.

BoolToStr liefert bei TRUE eine -1 als String zurück.

Ich hab die Funktion einfach neu geschrieben:

Code: Alles auswählen

 
function BoolToStr(b:Boolean):string;
begin
  if b then result:='1' else result:='0';
end;
 


Siro
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: array of bits -> byte komische Nebenwirkung

Beitrag von wp_xyz »

siro hat geschrieben:Ich hab die Funktion einfach neu geschrieben

Nicht nötig, es ist an alles gedacht, weil es überladene Varianten dieser Funktion gibt;

Code: Alles auswählen

 
function BoolToStr(B: Boolean; UseBoolStrs:Boolean=False): string;
function BoolToStr(B: boolean; const TrueS, FalseS: string): string;
 
WriteLn(BoolToStr(true));
WriteLn(BoolToStr(true), true);
WriteLn(BoolToStr(true), 'richtig','falsch');
WriteLn(BoolToStr(true), '1', '0')

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: array of bits -> byte komische Nebenwirkung

Beitrag von Mathias »

Ich habe ein Arry of Boolean [1-8] und möchte daraus ein byte machen.

Code: Alles auswählen

procedure TForm1.Button1Click(Sender: TObject);
var
  boolAr: bitpacked array[1..8] of boolean;
  b: byte absolute boolAr;
begin
  b := 0;
  boolAr[1] := True;
  boolAr[8] := True;
  ShowMessage(IntToHex(b, 2));
end

Wichtig ist das "bitpacked" bei der Deklaration.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: array of bits -> byte komische Nebenwirkung

Beitrag von siro »

Oho, das kannte ich auch noch nicht, dass es mehrere Varianten gibt, denen man sogar noch Werte übergeben kann.
Supi Info.

Aber wer liefert denn -1 als Default zurück, das ist schon ungewöhlich. Ich wüste jetzt keine Fall wo man eine -1 für True benötigt. :wink:

evtl. bezogen auf FlipFlops, habe eben das gefunden:
https://de.wikipedia.org/wiki/Boolesche_Variable
als Schaltung entspricht das Ein/Aus, oder aber –1/1, was einem Flipflop entspricht.

Siro
Zuletzt geändert von siro am So 23. Apr 2017, 09:43, insgesamt 2-mal geändert.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: array of bits -> byte komische Nebenwirkung

Beitrag von wp_xyz »

siro hat geschrieben:Aber wer liefert denn -1 als Default zurück, das ist schon ungewöhlich. Ich wüste jetzt keine Fall wo man eine -1 für True benötigt. :wink:

Die -1 habe ich schon bei Visual Basic gesehen. Wenn man in einem Byte alle Bits löscht, erhält man den Wert 0 - ist logisch. Wenn man alle Bits setzt, erhält man, je nach Typ Byte oder ShortInt, den Wert 255 oder -1. Insofern habe ich kein Problem mit -1. Es ist aber noch komplizierter, weil in Pascal alles was nicht 0 ist als TRUE interpretiert wird. Alles nur eine Frage der Definition und wie man 256 mögliche Zustände auf zwei (true und false) abbildet. Nachdem man sich bei BoolToStr im Fall von TRUE auf einen der möglichen 254 Werte entscheiden muss, hat man sich halt für den Wert 255 bzw. -1 entschieden und gleichzeitig mit dem Wissen, dass das willkürlich ist, die überladenen Varianten der Funktion eingeführt.

siro hat geschrieben:evtl. bezogen auf FlipFlops, habe eben das gefunden:
https://de.wikipedia.org/wiki/Boolesche_Variable
als Schaltung entspricht das Ein/Aus, oder aber –1/1, was einem Flipflop entspricht.

Das ist Unsinn. Die Definition von TRUE oder FALSE hat nichts mit einem Flipflop zu tun. Ein Flipflop ist eine Schaltung, die nach Anlegen eines Impulses in einen von zwei möglichen Zuständen schaltet (0V/5V, 0V/-12V, FALSE/TRUE, 0/1, -1/1 - egal wie man's nennt) und diesen Zustand beibehält, auch wenn der Impuls schon lange vorbei ist.
Zuletzt geändert von wp_xyz am So 23. Apr 2017, 09:44, insgesamt 2-mal geändert.

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: array of bits -> byte komische Nebenwirkung

Beitrag von siro »

Ist auch kein Problem für mich:
-1 ist ja Binär alle Bits gesetzt, was dann wieder (in C auch) TRUE entspricht. Alles was nicht NUll ist, ist TRUE;

Früher, in Turbo Pascal Zeiten wurde nur das unterste Bit ausgewertet, da hab ich oftmals
mit inc(b); das Bit umgedreht und aus FALSE wurde TRUE, das geht heut nicht mehr, grad nochmal probiert.
Für Einsteiger ist das aber sicher verwirrend, das TRUE -1 ist.

Code: Alles auswählen

 
 
var b:Boolean;
procedure TForm1.FormCreate(Sender: TObject);
begin
  b:=boolean(-1);   { ist TRUE }
  if b then caption:='True' else caption:='False';
end;
 

 

Code: Alles auswählen

 
var b:Boolean;
procedure TForm1.FormCreate(Sender: TObject);
begin
  b:=boolean(-1);   { ist TRUE }
  inc(b);             { b ist nun FALSE }
  if b then caption:='True' else caption:='False';
end;
 


egal ob der Standardtyp Byte oder Word oder...., durch das increment wird b zu Null und damit wieder FALSE
beim nächsten increment wieder TRUE, aber das wars dann erstmal für die nächsten xx increments.... :mrgreen:


@ente: so müsste dann dein Aufruf aussehen:

BoolToStr(ArrayBoolWerte[i], '1', '0');
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: array of bits -> byte komische Nebenwirkung

Beitrag von wp_xyz »

inc(b) ist aber auch die falsche Operation. Bei inc(b) wird der Bit-Wert der Speicherzelle, die b entspricht, um 1 erhöht, egal was der Datentyp ist, der auf b abgebildet wird. Schreib mal in deinen Code zusätzlich:

Code: Alles auswählen

   caption := Caption + ' ' + IntToStr(ord(b))

Da alles ungleich 0 als TRUE interpretiert wird, hast du nach dem ersten inc(b) TRUE, und das bleibt solange, bis die hinter b gespeicherten Bits den Wert 255 erreicht haben und auf 0 = FALSE überlaufen. Die oben erwähnte Definition von FALSE/TRUE ergibt halt leider nur 1 Wert für FALSE, aber 255 Möglichkeiten für TRUE. Man hätte es auch anders machen können: z.B. gerade Zahlen = FALSE, ungerade = TRUE. Hier würde dein Experiment funktionieren. Aber die aktuelle Definition entspricht ja auch eher der Wirklichkeit: Es gibt nur 1 Möglichkeit, dass zwei Zahlen gleich sind, aber unendlich viele, dass sie unterschiedlich sind.

Wenn du jedes mal hin und her schalten will, dann nehme: b := not b.

Mathias
Beiträge: 6160
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: array of bits -> byte komische Nebenwirkung

Beitrag von Mathias »

Ich habe folgendes probiert:

Code: Alles auswählen

var
  b: boolean;
  si: shortint absolute b;
 
begin
  b := False;
  WriteLn(shortint(b));
  WriteLn(shortint(si));
  b := not b;
  WriteLn(shortint(b));
  WriteLn(shortint(si));
 
  b := False;
  WriteLn(shortint(b));
  WriteLn(shortint(si));
  si := not si;
  WriteLn(shortint(b));
  WriteLn(shortint(si));
end

Das not beim Boolean, kehrt nur ein Bit, und bei ShortInt, wie erwarte, alle 8 Bits.
Somit ist es etwas komisch, das BoolToStr -1 liefert.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: array of bits -> byte komische Nebenwirkung

Beitrag von wp_xyz »

Wieso? Der Typ "boolean" ist 1 Byte groß und kann daher 256 verschiedene Werte einnehmen. Da nur zwei mögliche Werte für Boolean zugelassen sind, FALSE und TRUE, müssen diese 256 Zustände auf die beiden boolschen Zustände verteilt werden. In Pascal hat man gesagt: Die Null entspricht FALSE, alles andere entspricht TRUE. In dieser Richtung ist alles klar. Aber wenn du die andere Richtung gehst, so wie bei der Funktion BoolToStr(TRUE), musst du dich für einen aus den 255 TRUE-Zuständen entscheiden. Klar, man hätte 1 nehmen können, aber in der binären Darstellung ist das schon sehr seltsam: wieso soll %00000001 soll TRUE sein? Wieso nicht %10000000? Oder %0101010101? Besser wäre %11111111. Und das ist halt nun mal die Dezimalzahl -1 (oder 255). Aber wie schon gesagt: Diese Auswahl ist willkürlich, und wenn man damit nicht einverstanden ist, kann man einfach zusätzliche Parameter in der Funktion BoolToStr angeben.

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: array of bits -> byte komische Nebenwirkung

Beitrag von marcov »

Normale booleans sind noch immer 0 und 1. Das es ein Konversion Funktion gibt die ein String mit -1 herstellt tut davon nichts ab.

wp_xyz
Beiträge: 4869
Registriert: Fr 8. Apr 2011, 09:01

Re: array of bits -> byte komische Nebenwirkung

Beitrag von wp_xyz »

marcov hat geschrieben:Normale booleans sind noch immer 0 und 1. Das es ein Konversion Funktion gibt die ein String mit -1 herstellt tut davon nichts ab.

Was ist "normal"? In Pascal ist alles außer 0 TRUE.

Code: Alles auswählen

program Project1;
var
  i: Integer;
begin
  for i:=0 to 10 do
    WriteLn(i, ' ', boolean(i));
end.

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: array of bits -> byte komische Nebenwirkung

Beitrag von marcov »

Nein, nur 1 ist garantiert, der Rest ist zufällig. Es steht der Kodegenerator frei Kode zu generieren wie es gut acht.

Wenn man C booleans will, soll man (short/long- usw)BOOL nutzen.11

siro
Beiträge: 730
Registriert: Di 23. Aug 2016, 14:25
OS, Lazarus, FPC: Windows 11
CPU-Target: 64Bit
Wohnort: Berlin

Re: array of bits -> byte komische Nebenwirkung

Beitrag von siro »

Wo, in welcher Datei, ist denn TRUE und FALSE deklariert ?
Dann kann man das doch sehen was TRUE und was FALSE ist, denke ich.

in C habe ich es zum Beispiel so deklariert:

Code: Alles auswählen

 
 #define FALSE (0)            /* only the 0 is FALSE */
 #define TRUE  (! FALSE)      /* all others are TRUE */
  


damit ist eindeutig, daß ALLES außer 0 TRUE entspricht.

ich bin nur über das "Default" -1 gestolpert, weil das halte ich nicht unbedingt für Default :?
Siro
Zuletzt geändert von siro am Mo 24. Apr 2017, 16:32, insgesamt 1-mal geändert.
Grüße von Siro
Bevor ich "C" ertragen muß, nehm ich lieber Lazarus...

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: array of bits -> byte komische Nebenwirkung

Beitrag von marcov »

Das ist weil klassisch C kein Boolean Typ hat, nur Boolean Operatoren auf Integer.

FPC hat 2 boolean typen, und deren Logic kann man nicht ändern.

Antworten