Autor Beitrag
kamikaze
Hält's aus hier
Beiträge: 14

WIN XP pro
D6 enterprise
BeitragVerfasst: Sa 17.09.05 20:05 
Hab ne Frage:

ich hab ein array of boolean, da aber ein boolean 1 Byte speicher verbraucht, würd ich gerne die booleans in eine Bitkette umwandeln (für true 1 und flase 0) und je 32 davon als Integer wert in meinem array speichern, dann würd ich nur noch 1/8 des speichers verbrauchen.

Geht das was ich will überhaupt und wenn ja wie muss ich meine Bitkette umwandeln, dass sie genauso abgespeichert wird?

_________________
manchmal sind die Antworten die wir suchen einfacher als man denkt ;-)
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Sa 17.09.05 22:59 
Das geht relativ einfach:

Als erstes deklarierst Du einen

ausblenden Delphi-Quelltext
1:
2:
type
    TBooleanPack = set of 0..31;


und deklarierst dann eine Variable von diesem Typ:

ausblenden Delphi-Quelltext
1:
var BPack: TBooleanPack;					


Danach fügst Du die einzelnen Bits hinzu:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
BP := [];
For X:= 0 to 31 do
    If BooleanArray[X] Then
        Include(BP, X);


Danach kannst Du BP folgendermaßen als Integer casten:

ausblenden Delphi-Quelltext
1:
BPI := Integer(BP);					


HTH.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
kamikaze Threadstarter
Hält's aus hier
Beiträge: 14

WIN XP pro
D6 enterprise
BeitragVerfasst: So 18.09.05 16:52 
Das Problem ist wohl doch noch ein bisschen komplexer.

Also ich hatte ein array of boolean, jetzt hab ich ein array of Integer, jedes Integerfeld soll für je 32 Felder des Ursprungsarrays stehen ohne den Umweg über das Abspeichern im boolean array zu machen. Als Ausgangspunkt bekomm ich Zahlen, die die Stellen in meinem boolean array markiert haben, das ist ganz schön schwierig...

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
for i := 1 to length(Stringdo
 begin
  // in einer Prozedur wird aus einer Zeichenkette ein integer gemacht
  booleanArray[Integer] := true;
 end;


so sah es vorher aus.

_________________
manchmal sind die Antworten die wir suchen einfacher als man denkt ;-)
worm
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 135


D6 Prof
BeitragVerfasst: So 18.09.05 16:59 
Schau Dir mal TBits an, das ist eine vordefinierte Klasse in Delphi, die genau das erledigt. Allerdings erlaubt sie keinen direkten Zugriff auf das interne Integer-Array, dazu müsstest Du die classes.pas anpassen (da das Array im private-Teil deklariert ist, lässt sich das nicht mit einer eigenen von TBits abgeleiteten Klasse machen), also z.B. bei TBits unter public property BitArray: PIntegerArray read FBits einfügen (was ausdrücklich keine saubere Lösung wäre!).

_________________
In the beginning, the universe was created. This has made a lot of people very angry, and is generally considered to have been a bad move.
kamikaze Threadstarter
Hält's aus hier
Beiträge: 14

WIN XP pro
D6 enterprise
BeitragVerfasst: So 18.09.05 17:38 
weiß ja ich wie TBits die booleanwerte speichert ob mit 1 Bit oder 1 Byte, wenn es nur 1 bit abspeichert muss ich keinen Integer draus machen.

nochwas TBits hat die funktion OpenBit, die zeigt an wo das erste Feld mit False is, kann man das irgendwie so benutzen, dass man alle true Felder finden kann?

_________________
manchmal sind die Antworten die wir suchen einfacher als man denkt ;-)
worm
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 135


D6 Prof
BeitragVerfasst: So 18.09.05 18:15 
Nicht, ohne im Source der Classes.pas rumzupfuschen.
Vorschlag: Kehr doch in Deinem Programm die Bedeutung von False und True um (bzw. weise den Einträgen in TBits immer den gegenteiligen Wert zu als bisher), dann kannst Du mit OpenBit quasi das erste gesetzte Bit finden.
Ansonsten musst Du in einer Schleife TBits.Bits durchgehen, auch wenn mit einem direkten Zugriff auf das interne Integer-Array wesentlich performantere Lösungen möglich wären.

PS: Zu Deiner Frage: TBits speichert die Einträge Bit für Bit, sonst könnte man ja ein Array of Boolean nehmen und bräuchte die Klasse nicht.

_________________
In the beginning, the universe was created. This has made a lot of people very angry, and is generally considered to have been a bad move.
kamikaze Threadstarter
Hält's aus hier
Beiträge: 14

WIN XP pro
D6 enterprise
BeitragVerfasst: Mo 19.09.05 12:15 
OK, das Speicherproblem ist mit TBits gelöst, vielleicht mach ichs aber trotzdem zu Integer, um die gestezten Bits leichter zu finden.


Danke für die Hilfe.

_________________
manchmal sind die Antworten die wir suchen einfacher als man denkt ;-)
kamikaze Threadstarter
Hält's aus hier
Beiträge: 14

WIN XP pro
D6 enterprise
BeitragVerfasst: Do 22.09.05 20:11 
Hab noch was


user profile iconBenBE hat folgendes geschrieben:


type
TBooleanPack = set of 0..31;





kann man das set auch mit undefinierten Werten deklarieren und erst später die Werte festlegen??

_________________
manchmal sind die Antworten die wir suchen einfacher als man denkt ;-)
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Do 22.09.05 23:02 
Der Witz an dieser Definition des Datentyps ist ja gerade, dass Du für jedes Bit (0..31) eines Integers, genau ein Element hast, dass in diesem Typ enthalten sein kann. D.h. dieser Datentyp besitzt (je nach Compilereinstellungen) immer auf das nächste Byte aufgerundete Größe der Datenbits, die er enthält. Bit 0..31 also 32 Bits --> 4 Byte. Für 0..30 --> 31 Bits währen dies trotzdem 4 Byte, aber nur 31 genutzte Bits.

Eine Variable festlegung des Bereiches ist nicht möglich, da Datentypen zur Compiler-Laufzeit feststehen müssen. Du kannst Aber ein Array of Set 0..7 nutzen. Dann kannst Du auf 8 Bit Ebene immer erweitern.

Auf Bit 124 würdest Du dann mittels (124 mod 8in ArrBitSet[124 div 8] prüfen, was im Grundegenommen nichts anderes ist, was TBit auch macht.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.