Guillemouze
Messages postés991Date d'inscriptionsamedi 25 octobre 2003StatutMembreDernière intervention29 août 2013
-
9 sept. 2008 à 18:43
Guillemouze
Messages postés991Date d'inscriptionsamedi 25 octobre 2003StatutMembreDernière intervention29 août 2013
-
21 sept. 2008 à 13:17
Salut tout le monde,
une petite question me trotte dans la tete.
Est il possible de transtyper un set of QuelqueChose en entier ?
Parce que je me dis qu'il est bien possible que le compilateur stock ca sous forme de bits
Si j'ai
TX = (x1, x2, x3);
TXs = set of TX;
il fait surement :
[x1, x2] : 011
[x1, x3] : 101
[x1, x2, x3] : 111
[] : 000
cs_Kenavo
Messages postés702Date d'inscriptionvendredi 21 mars 2003StatutMembreDernière intervention 1 octobre 20095 21 sept. 2008 à 10:26
Salut, m'y revoilà !
type
TSetInt = (s1, s2, s3);
TSetInts = set of TSetInt;
procedure TForm1.FormCreate(Sender: TObject);
var T: TSetInts;
resu: byte; // ou Word ou DWord
begin T : = [s1];
resu := byte(T) ; // pas d'erreur du compilateur
T : = [s2];
resu := byte(T);
T := [s3];
resu := byte(T);
T := [s1, s2];
resu := byte([s1]); // là : erreur de transtypage !
end ;
Guillemouze
Messages postés991Date d'inscriptionsamedi 25 octobre 2003StatutMembreDernière intervention29 août 20136 21 sept. 2008 à 13:17
Ok, merci Kenavo :)
pour resumer :
type
TSetInt = (s1, s2, s3);
TSetInts = set of TSetInt;
const
TMax = [s1..s3];
TMid: TSetInts = [s2];
var
T: TSetInts;
R: integer;
begin
T := [s1, s3];
R := byte(T); // pour 1..8 éléments dans l'enum
R := Word(T); // " 9..16 "
R := Cardinal(T);// " 17..32 "
R := Byte(T); // variable du type du set : OK
R := Byte([s1, s3]); // pas possible si passage direct du set
R := Byte(TMax); // pas possible si constante non typée
R := Byte(TMid); // constante typée : OK
end;
en gros, ça revient a faire ceci :
const
sA = $01;
sB = $02;
sC = $04;
sAB = sA or sB;
sAC = sA or sC;
sBC = sB or sC;
sABC = sA or sB or sC;
donc oui les sets stocke dans des bits.
par contre avec les set of char ou set of byte, ça devient vite illisible, puisqu'il stocke le set sur 32 octets soit 256bits (8x32bits)
set avec moins de 8 valeurs = 8 bits (byte)
entre 8 et 16 valeurs = 16 bits (word)
entre 16 et 32 valeurs = 32 bits (doubleword)
entre 32 et 64 valeurs = 64 bits (2x doubleword)
entre 64 et 128 valeurs = 128 bits (4x doubleword)
entre 128 et 256 valeurs = 256 bits (8x doubleword)
on comprend pourquoi il limite le nombre de valeurs a 256!
f0xi
Messages postés4205Date d'inscriptionsamedi 16 octobre 2004StatutModérateurDernière intervention12 mars 202235 9 sept. 2008 à 20:54
et aussi :
if sValeur in sSetOfValeur then ..
sSetOfValeur = sSetOfValeur + [sValeur];
sSetOfValeur = sSetOfValeur - [sValeur];
et equivalent a :
if (vValeur and vVariable) <> 0 then .. (1101 and 0001 = 0001)
vVariable vVariable or vValeur (1100 or 0001 1101)
vVariable vVariable xor vValeur (1101 xor 0001 1100)
Guillemouze
Messages postés991Date d'inscriptionsamedi 25 octobre 2003StatutMembreDernière intervention29 août 20136 10 sept. 2008 à 22:33
c'est l'option que j'ai choisie, sauf que j'utilise un cardinal.
ca me donne un truc du genre:
TSetInt = (s1, s2, s3);
TSetInts = set of TSetInt;
function SetIntsToInt(const ASet: TSetInts): Cardinal;
var
i: TSetInt;
begin
assert(High(TSetInt) < sizeOf(Cardinal)*8); //on s'assure que toutes les valeurs peuvent etre contenues dans le cardinal
Result := 0;
for i := Low(TSetInt) to High(TSetInt) do
if i in ASet then
Inc(Result, 1 shl Ord(i));
end;