![]() |
Delphi Compiler - Mengen und Aufzählungstypen?? [INTERN]
Hi,
Ich habe ein kleines Problem (was könnts sonst sein :mrgreen:) Ich möchte in mein ![]() Also z.B.
Delphi-Quellcode:
DAs Problem ist, das ich mir nicht sicher bin, wie Delphi das verarbeitet.
type
TReplaceFlag = (rfReplaceAll, rfIgnoreCase); TReplaceFlags = set of TReplaceFlag; Ich habe bisher folgendes festgestellt, bin mir aber bei all dem noch nicht so sicher: Wenn man einen Aufzählungstyp hat wie TReplaceFlag, so ist der intern gespeicherte Wert für das erste Flag - also
Delphi-Quellcode:
Wenn man dagegen ein Set hat, scheint es so als ob der das folgendermaßen macht:
const
rfReplaceAll = 0; rfIgnoreCase = 1;
Delphi-Quellcode:
Kann mir das jmd. bestätigen oder sonst noch etwas dazu beitragen?
var
IstEnthalten_rfReplaceAll : Boolean; IstEnthalten_rfReplaceAll : Boolean; begin IstEnthalten_rfReplaceAll := (round(IntPower(2, fIgnoreCase+1)) and ReplaceFlags) <> 0; IstEnthalten_rfIgnoreCase := (round(IntPower(2, fIgnoreCase+1)) and ReplaceFlags) <> 0; MFG |
Re: Delphi Compiler - Mengen und Aufzählungstypen?? [INTERN]
Bei Sets mit vorfefinierten werten, sowie bei Integersets, ist es nicht so eindeutig,
aber im Allgemeinen:
Delphi-Quellcode:
Werte sind alle durchnummeriert, von 0 beginnend
type e = (a, b, c, d);
s = set of e; // oder type s = set of (a, b, c, d); a=0, b=1, c=2 und d=3 das Set ist dann ein "Bit-Array" aller werte Bit 0 = a Bit 1 = b Bit 2 = c Bit 3 = d ergibt also folgendes bitmaskte = $1 shl Wert; $0001 = a $0002 = b $0004 = c $0008 = d $0010 = ... Hat das Set also einen wert von $0005, dann sind a und c gesetzt.
Delphi-Quellcode:
Dann sind in Delphi die Sets so groß/klein wie nötig
$0005 = (1 shl 0) {1} or (1 shl 2) {4}
- bis 8 Werte = Byte, bis 16 Werte = Word usw. |
Re: Delphi Compiler - Mengen und Aufzählungstypen?? [INTERN]
Das mit dem shl hab ich mir auch schon gedacht ;)
Hatte es vorhin nur noch nicht geschrieben, weil ichs noch nachprüfen wollte. Also ist das damit ja relativ leicht. Aber wie sieht es aus mit der größe das Datentypes. Also wenn so ein Set nur max 8 Eleente enthält - ist das dann nur ein Byte groß? und wie siehts aus wenns mehr enthält?? MFG |
Re: Delphi Compiler - Mengen und Aufzählungstypen?? [INTERN]
1-8 = 1 Byte
9-16 = 2 Byte (Word) 17-32 = 4 Byte (LongWord) 33-64 = 8 Byte (UInt64) und dann jeweils in 4 Byte-Schritten (glaub ich) bis 32 Byte = maximale 256 Werte |
Re: Delphi Compiler - Mengen und Aufzählungstypen?? [INTERN]
Mit ord() kannst du die Position ermitteln.
Es gibt auch den Befehl if (x in set) then |
Re: Delphi Compiler - Mengen und Aufzählungstypen?? [INTERN]
Ich frage mich aber...
was wäre schneller im code? Wenn ich jetzt intern das so mache, das ich mit dem Operator "in" arbeiten kann... oder das manuell mache. Also:
Delphi-Quellcode:
EDIT: Wobei ich glaube 2. ist besser / einfacher ;)
Result := (1 shl FlagID and Flags) <> 0;
EDIT 2: Aber ich frage mich, wie ich das mit Sets mit mehr als 32 (bzw. 64) Elementen mache - also wenn ich den Operator and nicht mehr verwenden kann... MFG |
Re: Delphi Compiler - Mengen und Aufzählungstypen?? [INTERN]
Wie sieht denn deine Speicherverwaltung aus?
Bzw, wenn du auf reale SETs zugreifen willst, dann bleibt dann eh kein anderer Weg abfragen:
Delphi-Quellcode:
OK, Byteweise ginge auch, auch wenn nicht unbedingt efektiv:
if count <= 8 then result := ($1 shl value) and PByte(@data) <> 0
else if count <= 16 then result := ($1 shl value) and PWord(@data) <> 0 else result := ($1 shl (value mod 32)) and PLongWord(@data)[value div 32] <> 0; //result := ($1 shl (value and 31)) and PLongWord(@data)[value shr 5] <> 0;
Delphi-Quellcode:
result := ($1 shl (value mod 8)) and PByte(@data)[value div 8] <> 0;
//result := ($1 shl (value and 7)) and PByte(@data)[value shr 3] <> 0; entfernen (ohne "or i") und setzen (mit "or i"):
Delphi-Quellcode:
if count <= 8 then begin
i := 1 shl value; PByte(@data) := (PByte(@data) and not i) or i; end else if count <= 16 then begin i := 1 shl value; PWord(@data) := (PWord(@data) and not i) or i; end else begin i := 1 shl (value mod 32); i2 := value div 32; PLongWord(@data)[i2] := (PLongWord(@data)[i2] and not i) or i; //i := 1 shl (value and 31); //i2 := value shr 5; //PLongWord(@data)[i2] := (PLongWord(@data)[i2] and not i) or i; end; |
Re: Delphi Compiler - Mengen und Aufzählungstypen?? [INTERN]
Oder man macht das in Assembler
Sei EAX=@Data und EDX=count.
Delphi-Quellcode:
Das schöne an diesen Befehlen ist, daß edx (also count) im Bereich −2^31 bis 2^31 − 1 sein darf.
bt [eax],edx // setzt CF=1 wenn das Bit count = 1 ist
bts [eax],edx // setzt CF=1 wenn das Bit count = 1 ist und setzt dann das Bit=1 btr [eax],edx // setzt CF=1 wenn das Bit count = 1 ist und setzt dann das Bit=0 btc [eax],edx // setzt CF=1 wenn das Bit count = 1 ist und "dreht es dann um" Entsprechende Funktionen könnte man so gestalten:
Delphi-Quellcode:
FUNCTION IsBitSet(p:pointer; count:integer):Boolean;
asm bt [eax],edx setc al end; FUNCTION SetBit(p:pointer; count:integer):Boolean; asm bts [eax],edx setc al end; FUNCTION ClearBit(p:pointer; count:integer):Boolean; asm btr [eax],edx setc al end; FUNCTION ToggleBit(p:pointer; count:integer):Boolean; asm btc [eax],edx setc al end; |
Re: Delphi Compiler - Mengen und Aufzählungstypen?? [INTERN]
@Amateurprofi:
Danke! Diese ASM Funktionen sind genau das was ich brauchte. Denn mir war schleierhaft, wie ich ein einzelntes Bit innerhalb eines Wertes mit einer Größe über 64 Bit abfragen konnte. Ich werde das ganze dann mal ausprobieren. :coder2: MFG |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06: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