IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Delphi Discussion :

Set of mal compris ?


Sujet :

Langage Delphi

  1. #1
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 487
    Points : 3 120
    Points
    3 120
    Par défaut Set of mal compris ?
    Bonjour

    Je suis étonné du fonctionnement du code suivant qui affiche OK :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    type
      TNiveau = set of 1..255;
     
    procedure TForm9.Button6Click(Sender: TObject);
    var
      Niveau: TNiveau;
    begin
      Niveau := [];
      Include(Niveau, 0);
      if 0 in Niveau then
        ShowMessage('ok');
    end;
    Le fait que 0 ne fasse pas partie de l'ensemble TNiveau ne devrait-il pas déclencher une erreur ?
    J-L aka Papy pour les amis

  2. #2
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 374
    Points : 3 152
    Points
    3 152
    Par défaut
    Bonjour,

    moi, cela me parait logique, puisque tu ajoutes l’élément 0 à l'ensemble Niveau ?

    L'aide de Delphi dit :
    S est une variable de type ensemble et I est une expression de type compatible avec le type de base de S.
    C'est comme si tu faisais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Niveau := Niveau + [0] ;
    A+
    Charly

  3. #3
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 875
    Points : 11 359
    Points
    11 359
    Billets dans le blog
    6
    Par défaut
    Bonsoir,
    C'est effectivement inattendu !
    Même en activant la directive de vérification d'étendue, un type ensemble d'éléments de type A peut inclure des éléments similaires, mais pas de type A...
    C'est donc permis, comme le rappelle Charly910, mais pas sécurisant par rapport au fonctionnement intuité.
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  4. #4
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 374
    Points : 3 152
    Points
    3 152
    Par défaut
    Bonsoir,

    c'est vrai que ce n'est pas sécurisant et c'est étonnant de la part d'un langage comme Pascal !

    Les ensembles peuvent donc être agrandis !

    A+
    Charly

  5. #5
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 374
    Points : 3 152
    Points
    3 152
    Par défaut
    Ce qui est encore plus inquiétant, c'est que sans le Include, si on fait :

    ça ne plante pas , alors que l'on est en dehors de l'intervalle 1..255

    A+
    Charly

  6. #6
    Membre expert
    Avatar de Charly910
    Homme Profil pro
    Ingénieur TP
    Inscrit en
    Décembre 2006
    Messages
    2 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur TP
    Secteur : Bâtiment Travaux Publics

    Informations forums :
    Inscription : Décembre 2006
    Messages : 2 374
    Points : 3 152
    Points
    3 152
    Par défaut
    Ce qui est curieux, c'est que 0 ne pose pas de problème, alors que 300 par exemple provoque une erreur à l'exécution !!

    A+
    Charly

  7. #7
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 487
    Points : 3 120
    Points
    3 120
    Par défaut
    ça me réconforte, je ne suis pas le seul à trouver ça étrange.

    Je n'avais pas essayé de mettre 300 parce que les valeurs dans les ensembles vont forcément de 0 à 255.
    Mais j'essaierai 256 pour voir
    J-L aka Papy pour les amis

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 592
    Points : 25 273
    Points
    25 273
    Par défaut
    Il serait intéressant de vérifier quel bit est actif selon la valeur !
    Est-qu'un set qui ne commence pas à zéro, commence quand même à zéro

    Voir la différence en mémoire, un set c'est juste un tableau de bit,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    type
      TNiveau = set of 1..255;
     
    Include(Niveau, 0); bit 0 dans le premier byte soit 0000 0001
    Include(Niveau, 1); bit 1 dans le premier byte soit 0000 0010 
     
    if (PByte(@Niveau)^ and 1) = 1 then
      ShowMessage('0');
     
    if (PByte(@Niveau)^ and 2) = 2 then
      ShowMessage('1');
    ce qui fonctionnerait de la même façon que set of 0..255; ... car c'est la valeur de l'enum qui indique le bit, il ne font pas de valeur de l'enum - valeur de début


    un rappel pour connaître le nombre d'item actif, ça date de Delphi 5 mais je ne crois pas que cela ait changé

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    function SizeOfSetShai(PSet: pointer; SizeOfSet: Byte = 32): Integer;
    const
      CountBitByHalfByte: array[0..15] of Integer = (0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4);
    type
       PHashSet = ^THashSet;
       THashSet = array [0..31] of Byte;
    var
       i, vHS: Byte;
       pHS: PHashSet;
    begin
        Result := 0;
        pHS := PSet;
        for i := 0 to SizeOfSet-1 do
        begin
            vHS := pHS^[i] and $0F;
            if vHS > 0 then
               Inc(Result, CountBitByHalfByte[vHS]);
     
            vHS := pHS^[i] shr 4;
            if vHS > 0 then
            begin
               Inc(Result, CountBitByHalfByte[vHS]);
            end;
        end;
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  9. #9
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 487
    Points : 3 120
    Points
    3 120
    Par défaut
    @ShaiLeTroll : ton code de test affiche bien 0 puis 1 avec les boites de dialogues.
    Je l'ai même étendu un peu et chaque test passe à True sans problème.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
      Include(Niveau, 0);
      Include(Niveau, 1);
      Include(Niveau, 2);
      Include(Niveau, 3);
     
      if (PByte(@Niveau)^ and 1) = 1 then
        ShowMessage('0');
     
      if (PByte(@Niveau)^ and 2) = 2 then
        ShowMessage('1');
     
      if (PByte(@Niveau)^ and 3) = 3 then
        ShowMessage('2');
     
      if (PByte(@Niveau)^ and 4) = 4 then
        ShowMessage('3');
    Par contre je viens de refaire un test en commentant Include(Niveau, 2);
    Résultat affiché : 0 puis 1 puis 2 :-(

    en commentant seulement Include(Niveau, 0);
    Résultat : 1 puis 3

    Plus ça va moins je comprends
    J-L aka Papy pour les amis

  10. #10
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 592
    Points : 25 273
    Points
    25 273
    Par défaut
    Attention, ces tests ne sont pas les bons
    Il faut reflechir en binaire donc en puissance de 2

    3 = 0011 soit include (0) 0001 et (1) 0010 ce ne qui ne correspond pas à include 2 (0100) soit 4 en décimal

    Comme on ne peut pas écrire du binaire dans le code, on peut attirer l'oeil en écrivant en hexa

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    procedure TForm1.Button1Click(Sender: TObject);
    type
      TNiveau = set of 1..255;
    var
      Niveau: TNiveau;
    begin
      Include(Niveau, 0); // en mémoire, tableau de 32 octets avec le premier byte à 0000 0001 = 01
      Include(Niveau, 1); // en mémoire, tableau de 32 octets avec le premier byte à 0000 0010 = 02
      Include(Niveau, 2); // en mémoire, tableau de 32 octets avec le premier byte à 0000 0100 = 04
      Include(Niveau, 3); // en mémoire, tableau de 32 octets avec le premier byte à 0000 1000 = 08
     
      if (PByte(@Niveau)^ and $01) = $01 then
        ShowMessage('0');
     
      if (PByte(@Niveau)^ and $02) = $02 then
        ShowMessage('1');
     
      // Test faux !
      if (PByte(@Niveau)^ and 3) = 3 then
        ShowMessage('2 faux positif via 3');
     
      // Test corrigé !
      if (PByte(@Niveau)^ and $04) = $04 then
        ShowMessage('2');
     
      Exclude(Niveau, 2);
      // Test faux !
      if (PByte(@Niveau)^ and 3) = 3 then
        ShowMessage('2 faux positif via 3');
     
      // Test corrigé !
      if (PByte(@Niveau)^ and $04) = 0 then
        ShowMessage('2 absent');
     
     
      if (PByte(@Niveau)^ and $08) = $08 then
        ShowMessage('3');
    end;

    Cette approche pour les tests ne fonctionnent que jusqu'a $8000 0000 0000 000 pour le bit 63, la manipulation d'un set en interne par Delphi c'est de décalage et mask binaire, mais connaitre cela permet de comprendre qu'un set of 0..255 c'est un bloc mémoire de 32 octets, soit 256 bit, chaque bit indique la présence d'une valeur entre 0 et 255, la valeur servant pour le shl.
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  11. #11
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 487
    Points : 3 120
    Points
    3 120
    Par défaut
    Je comprends mieux.

    D'ailleurs, je viens de tester le code suivant;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
      Include(Niveau, 0); // en mémoire, tableau de 32 octets avec le premier byte à 0000 0001
      Include(Niveau, 1); // en mémoire, tableau de 32 octets avec le premier byte à 0000 0010
      Include(Niveau, 2); // en mémoire, tableau de 32 octets avec le premier byte à 0000 0100
      Include(Niveau, 3); // en mémoire, tableau de 32 octets avec le premier byte à 0000 1000
     
      G := PByte(@Niveau)^;
    G vaut 15, donc, 1111 en binaire.

    Bon, il reste quand même que Delphi accepte l'ajout d'une valeur qui ne fait pas partie de la plage prévue et ça c'est un peu ennuyeux.
    J-L aka Papy pour les amis

  12. #12
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 592
    Points : 25 273
    Points
    25 273
    Par défaut
    A toi d'ajouter les contrôles, je pense que c'est la particularité d'un intervalle, 1..255 c'est plus un intervalle qu'une énumération, cette dernière étant plus strict.

    Je ne vois pas en quoi cela peut être ennuyeux, un code correctement encapsulé doit généré une erreur ERangeError si une valeur d'une source externe n'est pas comprise dans l'intervalle.
    Et dans le cas d'un source interne au programme, je ne vois pas comment cela pourrait être en dehors

    source externe = saisie utilisateur, fichier, base de donnée ...
    source interne = calcul, boucle, ...

    ta boucle, faut toujours l'écrire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    type
      TNiveauRange = 1..255;
      TNiveau = set of TNiveauRange;
     
    for I := Low(TNiveauRange) to High(TNiveauRange) do
    d'ailleurs, j'aurais plutôt déclaré ainsi

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    type
      TNiveau = 1..255;
      TNiveaux = set of TNiveau;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    type
      TLevel = 1..255;
      TLevels = set of TLevel;

    Et le contrôle est effectué par le compilateur si l'on découpe en deux TNiveau et TNiveaux, c'est l'intervalle qui est protégée, pas l'ensemble
    Et si c'est au RunTime, il y a une directive de compilation, je la déconseille parce qu'elle se rajoute partout, faire soit même le contrôle explicite, c'est facile et en plus cela démontre que l'on connaît l'existence d'une source externe
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
     
     
    type
      TNiveau = 1..255;
      TNiveaux = set of TNiveau;
    var
      Niveau: TNiveau;
      Niveaux: TNiveaux;
      I: Byte;
    begin
      //Niveau := 0; / [dcc64 Erreur]: E1012 L'expression constante dépasse les limites de sous-étendue
     
      {$RANGECHECKS ON}
      I := 0;
      Niveau := I; // a déclenché la classe d'exception ERangeError avec le message 'Range check error'.
      {$RANGECHECKS OFF}
     
      // je préfère le faire en toute connaissance de cause et avec un message plus précis
      if (Ord(Low(TNiveau)) <= I) and (I <= Ord(High(TNiveau))) then
        Niveau := I
      else
        raise ERangeError.CreateFmt('Valeur %d invalide pour TNiveau', [I]);  // a déclenché la classe d'exception ERangeError avec le message 'Valeur 0 invalide pour TNiveau'.
     
     
      Include(Niveaux, Niveau); // en mémoire, tableau de 32 octets avec le premier byte à 0000 0001 = 01
     
      Include(Niveaux, Niveau); // en mémoire, tableau de 32 octets avec le premier byte à 0000 0001 = 01
      Niveau := 1;
      Include(Niveaux, Niveau); // en mémoire, tableau de 32 octets avec le premier byte à 0000 0010 = 02
      Niveau := 2;
      Include(Niveaux, Niveau); // en mémoire, tableau de 32 octets avec le premier byte à 0000 0100 = 04
      Niveau := 3;
      Include(Niveaux, Niveau); // en mémoire, tableau de 32 octets avec le premier byte à 0000 1000 = 08
     
      if (PByte(@Niveaux)^ and $01) = $01 then
        ShowMessage('0');
     
      if (PByte(@Niveaux)^ and $02) = $02 then
        ShowMessage('1');
     
      // Test faux !
      if (PByte(@Niveaux)^ and 3) = 3 then
        ShowMessage('2 faux positif via 3');
     
      // Test corrigé !
      if (PByte(@Niveaux)^ and $04) = $04 then
        ShowMessage('2');
     
      Exclude(Niveaux, 2);
      // Test faux !
      if (PByte(@Niveaux)^ and 3) = 3 then
        ShowMessage('2 faux positif via 3');
     
      // Test corrigé !
      if (PByte(@Niveaux)^ and $04) = 0 then
        ShowMessage('2 absent');
     
     
      if (PByte(@Niveaux)^ and $08) = $08 then
        ShowMessage('3');
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  13. #13
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 487
    Points : 3 120
    Points
    3 120
    Par défaut
    Je suis bien d'accord avec toi sur tous ces points.
    Simplement si je fais le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    type
      Cartes = (Pique, Coeur, Carreau);
      TCarte = set of Cartes;
     
    procedure TForm9.Button6Click(Sender: TObject);
    var
      Carte: set of (Pique, Trefle, Coeur);
    begin
     
      Carte := [];
      Include(Carte, Pique);  // OK
      Include(Carte, Cartes.Carreau); // NOK
      Include(Carte, Ord(Cartes.Carreau)); // NOK
    Sur le troisième include, on pourrait pourtant considérer que Ord(Cartes.Carreau) vaut la même chose (en terme de position dans le tableau) que Coeur.
    Pourtant ça ne compile pas.

    Ce que je voulais dire c'est que dans ce cas les limites sont forcément respectées.
    Le type défini permet donc certaines choses .. ou pas ...

    En tous cas, merci une fois de plus pour les explications.
    J-L aka Papy pour les amis

  14. #14
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 487
    Points : 3 120
    Points
    3 120
    Par défaut
    une dernière question !

    Pour le fun, j'essaie de copier le contenu de Niveau dans un tableau de byte mais mon tableau se remplit de valeurs farfelues.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
      Th: array[0..255] of byte;
    begin
     
      FillChar(Th, sizeOf(Th), #0);  // Toutes les valeurs sont bien initialisées, j'ai vérifié
     
      Niveau := [];
      Include(Niveau, 0); // en mémoire, tableau de 32 octets avec le premier byte à 0000 0001
      Include(Niveau, 1); // en mémoire, tableau de 32 octets avec le premier byte à 0000 0010
      Include(Niveau, 2); // en mémoire, tableau de 32 octets avec le premier byte à 0000 0100
      Include(Niveau, 3); // en mémoire, tableau de 32 octets avec le premier byte à 0000 1000
      Include(Niveau, 255); // en mémoire, tableau de 32 octets avec le premier byte à 0000 1000
     
      Move(Niveau, Th, SizeOf(Th));
    (15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 64, 217, 75, 3, 48, 227, 76, 3, 236, 243, 25, 0, 173, 94, 83, 0, 28, 15, 85, 0, 64, 217, 75, 3, 63, 15, 85, 0, 84, 244, 25, 0, 77, 26, 85, 0, 64, 217, 75, 3, 60, 89, 83, 0, 84, 244, 25, 0, 108, 246, 25, 0, 64, 217, 75, 3, 144, 179, 29, 119, 40, 8, 0, 0, 254, 255, 255, 255, 32, 243, 25, 0, 214, 146, 41, 117, 0, 240, 15, 2, 0, 0, 0, 0, 220, 73, 63, 82, 21, 2, 0, 0, 238, 9, 19, 0, 0, 0, 0, 0, 252, 200, 26, 119, 3, 0, 0, 0, 240, 242, 25, 0, 22, 0, 0, 0, 196, 244, 25, 0, 112, 55, 42, 117, 196, 30, 9, 39, 254, 255, 255, 255, 192, 243, 25, 0, 174, 85, 244, 115, 238, 9, 19, 0, 0, 0, 0, 0, 21, 2, 0, 0, 238, 9, 19, 0, 28, 86, 244, 115, 243, 0, 0, 0, 0, 0, 0, 0, 238, 9, 19, 0, 0, 0, 0, 0, 205, 171, 186, 220, 192, 9, 127, 1, 243, 0, 0, 0, 238, 9, 19, 0, 68, 244, 25, 0, 42, 127, 41, 117, 112, 104, 136, 221, 238, 9, 19, 0, 68, 244, 25, 0, 111, 129, 41, 117, 108, 127, 41, 117, 184, 78, 63, 82)

    Je comprends bien qu'il y a une erreur quelque part mais je n'arrive pas à voir où.

    Ce n'est peut-être pas possible ??
    J-L aka Papy pour les amis

  15. #15
    Modérateur
    Avatar de tourlourou
    Homme Profil pro
    Biologiste ; Progr(amateur)
    Inscrit en
    Mars 2005
    Messages
    3 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Biologiste ; Progr(amateur)

    Informations forums :
    Inscription : Mars 2005
    Messages : 3 875
    Points : 11 359
    Points
    11 359
    Billets dans le blog
    6
    Par défaut
    Bonsoir,
    Si j'ai compris ce que tu souhaitais faire, on peut comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    var
      Niveau: set of 1..255;
      HackSet: array[0..31] of Byte absolute Niveau;
    begin
      ZeroMemory(HackSet);
      Include(Niveau, 0);
      ShowMessage(HackSet[0].ToString);
    end;
    Delphi 5 Pro - Delphi 11.3 Alexandria Community Edition - CodeTyphon 6.90 sous Windows 10 ; CT 6.40 sous Ubuntu 18.04 (VM)
    . Ignorer la FAQ Delphi et les Cours et Tutoriels Delphi nuit gravement à notre code !

  16. #16
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 592
    Points : 25 273
    Points
    25 273
    Par défaut
    Effectivement, 256 bit = 32 byte !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  17. #17
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 487
    Points : 3 120
    Points
    3 120
    Par défaut
    Citation Envoyé par tourlourou Voir le message
    Bonsoir,
    Si j'ai compris ce que tu souhaitais faire, on peut comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    var
      Niveau: set of 1..255;
      HackSet: array[0..31] of Byte absolute Niveau;
    begin
      ZeroMemory(HackSet);
      Include(Niveau, 0);
      ShowMessage(HackSet[0].ToString);
    end;
    Alors oui, c'est ça sauf que ça ne donne pas exactement le résultat que je voulais
    D'abord, mais peut-être que ça vient de la version Delphi (XE7) j'ai du remplacer la première ligne par ZeroMemory(@HackSet[0], SizeOf(HackSet));

    Ensuite voici ce que ça donne dans le tableau :

    Nom : resultat.jpg
Affichages : 111
Taille : 92,2 Ko

    Alors que je cherchais plutôt à avoir une sorte de représentation binaire du genre

    1, 1, 1, 1, 0,0,0,0,0,0,

    Même si le 15 obtenu est bien égal au binaire 1111
    J-L aka Papy pour les amis

  18. #18
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 592
    Points : 25 273
    Points
    25 273
    Par défaut
    Tu peux utiliser IntToBin et la simplfier en ByteToBin pour l'utiliser dans MemoryToBin
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  19. #19
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 592
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 592
    Points : 25 273
    Points
    25 273
    Par défaut
    Et voilà ce que cela donne
    avec une représentation si l'on est plutôt BigEndian ou LittleEndian, toujours délicat de représenter un tableau de bit en LittleEndian (cas de Delphi VCL)
    RevertEndianness à False c'est LittleEndian, une représentation habituelle en informatique, avec le bit de poids fort à gauche et le bit 0 à droite
    RevertEndianness à True, c'est BigEndian, pour une lecture plus humaine à voir un comme un tableau de [0..255] se lisant de gauche (0) à droite (255)


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    procedure TForm1.Button1Click(Sender: TObject);
     
      function ByteToBin(Value: Byte; RevertEndianness: Boolean = False): string;
      var
        I: Byte;
        C: Char;
      begin
        SetLength(Result, 8);
        for I := 7 downto 0 do
        begin
          C := Chr(Ord('0') + Ord((Value shr I) and 1));
          if RevertEndianness then
            Result[I+1] := C
          else
            Result[8-I] := C
        end;
      end;
     
      function MemoryToBin(Mem: Pointer; Len: Integer; RevertEndianness: Boolean = False): string;
      var
        P, PEnd: PByte;
      begin
        P := Mem;
        // PEnd := Mem + Len; // avec arithmétique des pointeurs
        PEnd := PByte(NativeUInt(Mem) + Len); // sans arithmétique des pointeurs
        while P < PEnd do
        begin
          if RevertEndianness then
            Result := Result + ByteToBin(P^, RevertEndianness)
          else
            Result := ByteToBin(P^, RevertEndianness) + Result; 
     
          Inc(P);
        end;
      end;
     
    var
      Niveau: set of 1..255;
      HackSet: array[0..31] of Byte absolute Niveau;
    begin
      ZeroMemory(@HackSet, SizeOf(HackSet));
      Include(Niveau, 0);
      Include(Niveau, 1);
      Include(Niveau, 2);
      Include(Niveau, 3);
      Include(Niveau, 31);
      Include(Niveau, 254);
      // RevertEndianness à False montre comme si c'était un grand chiffre, bit 255 à bit 0
      // 0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000001111
      ShowMessage(MemoryToBin(@HackSet, SizeOf(HackSet), False));
      // RevertEndianness à True montre comme un array[0..255] of bit, soit bit 0 à bit 255 
      // 1111000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010
      ShowMessage(MemoryToBin(@HackSet, SizeOf(HackSet), True));
    end;
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  20. #20
    Membre expert

    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2007
    Messages
    3 487
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Novembre 2007
    Messages : 3 487
    Points : 3 120
    Points
    3 120
    Par défaut
    Trop bien ! C'est exactement ce que je cherchais à faire.

    Toujours aussi fort !

    Je vais étudier ton code pour l'intégrer dans mes connaissances.

    Merci (une fois de plus)
    J-L aka Papy pour les amis

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. strtoul mal compris...
    Par SPACHFR dans le forum Débuter
    Réponses: 5
    Dernier message: 31/05/2007, 16h33
  2. [MySQL] Classe database + connexion multiple + principe mal compris
    Par Rodrigue dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 14/08/2006, 14h06
  3. [C++]Code mal compris
    Par fafa139 dans le forum MFC
    Réponses: 5
    Dernier message: 11/05/2006, 13h51
  4. [C++]Code mal compris
    Par fafa139 dans le forum C++
    Réponses: 5
    Dernier message: 11/05/2006, 13h51

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo