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 Pascal Discussion :

Transformer un champ booléen en chaîne de caractères


Sujet :

Langage Pascal

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    86
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 86
    Par défaut Transformer un champ booléen en chaîne de caractères
    Bonjour,

    Je voudrais savoir le code à saisir pour faire qu'un champ boolean devienne string dans une chaine de caractère ?

    je sais faire le FloatToString pour identifier un montant comme étant du texte, mais là ce que je voudrais c'est faire que j'ai oui ou non à la place de 0 ou 1 de mon champ booléen.

    Merci d'avance

    Carpe Diem

  2. #2
    Membre chevronné
    Avatar de richard
    Homme Profil pro
    Inscrit en
    Avril 2002
    Messages
    475
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Avril 2002
    Messages : 475
    Par défaut
    Pourquoi faire un cast ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
     
    Var 
      MyBool : Boolean;
      BoolString : String;
     
    Begin
      IF MyBool=True Then BoolString:='Oui'
        ELSE BoolString:='Non';
    end;
    Il suffit de mettre ça dans une fonction et le tour est joué, non ?

  3. #3
    Membre Expert
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    const
      BoolToStr : array[boolean] of string = ('0', '1');
      BoolToLongStrEn : array[boolean] of string = ('false', 'true');
      BoolToLongStrFr : array[boolean] of string = ('faux', 'vrai');
      BoolToOnOff : array[boolean] of string = ('off', 'on');
      BoolToOuiNon : array[boolean] of string = ('non', 'oui');
      BoolToYesNo : array[boolean] of string = ('no', 'yes');
    si array[boolean] ne compile pas redéclarer :

    array[false..true]

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    var
      Boo : boolean;
    begin
      Boo := true;
     
      writeln(BoolToStr[Boo]);
      writeln(BoolToLongStrEn[Boo]);
    end;
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  4. #4
    Membre chevronné
    Avatar de richard
    Homme Profil pro
    Inscrit en
    Avril 2002
    Messages
    475
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Puy de Dôme (Auvergne)

    Informations forums :
    Inscription : Avril 2002
    Messages : 475
    Par défaut
    Sans vouloir alimenter la polémique, une fonction intégrant le code que j'ai donné n'est-elle pas plus simple ?

    Quels sont les avantages du type de code que tu proposes ? Dans quelle situation par exemple (c'est une vraie question, ça m'intéresse) ?

    Merci<.

  5. #5
    Membre Expert
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Par défaut
    Citation Envoyé par richard Voir le message
    Sans vouloir alimenter la polémique, une fonction intégrant le code que j'ai donné n'est-elle pas plus simple ?
    plus simple, oui et non, d'ailleur une correction, il n'est pas necessaire de comparer explicitement un boolean avec true ou false :

    if Bool then ... remplace : if bool = true then
    if not Bool then ... remplace : if bool = false then

    plus parlante dans le sens ou on vois ce qui est fait dans la condition vrai et fausse.
    par contre, elle génére deux fois le même code dans le cas :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if bool then
      S := 'bonjour'
    else
      S := 'au revoir';
    d'ailleur un case of serait encore plus explicite :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    case bool of
      false : s := 'au revoir';
      true  : s := 'bonjour';
    end;
    Citation Envoyé par richard Voir le message
    Quels sont les avantages du type de code que tu proposes ? Dans quelle situation par exemple (c'est une vraie question, ça m'intéresse) ?
    l'avantage est surtout dans les exemples comme dans ce sujet, l'assignation de valeur différente si true ou false.
    l'avantage de telles constantes est d'avoir un semblant de truc qui s'utilise comme une fonction mais sans le CALL necessaire à l'appel de cette fonction.

    par exemple, la fonction BoolToStr qu'on trouve dans Delphi, necessite un call puis différent test pour retourner True ou False ou 0 ou 1 dans une chaine.
    si on l'appel une fois ... les perf ne seront pas importantes ... donc l'intérêt ici n'est pas flagrant.

    par contre, dans une liste, une boucle etc, ou l'on doit renvoyer par exemple une case coché (checklistbox), une multi-sélection, ou avoir une colorisation différente des lignes pair et impair, il sera plus évident d'utiliser ce genre de constante car elle ne demande qu'un test et un mov donc trés rapide et n'handicaperons pas les performances d'affichage ou de traitement de la boucle.

    exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const
      Colors : array[boolean] of integer = (clWhite, clSilver);
      Styles : array[boolean] of TFontStyles = ([], [fsBold]);
    begin
      for n := 1 to 1000000 do
      begin
        Canvas.Brush.Color := Colors[(N and $1) = 0];
        Canvas.Font.Style := Styles[odSelected in State];
        Canvas.TextOut(Rect.Left+2, Rect.Top+2, 'truc');
      end;
    end;
    le code precedent sera plus performant et concis que celui ci :
    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
    begin
      for n := 1 to 1000000 do
      begin
        if odd(n) then
          Canvas.Brush.Color := clWhite
        else
          Canvas.Brush.Color := clSilver;
     
        if odSelected in State then
          Canvas.Font.Style := [fsBold]
        else
          Canvas.Font.Style := [];
     
        Canvas.TextOut(Rect.Left+2, Rect.Top+2, 'truc');
      end;
    end;
    de plus, elle n'est pas limité, on peu definir quasiment n'importe quoi dans le array[boolean].
    string, entier, flottant, procedure, objet, couleur etc etc.
    on peut même faire plus complexe et obtenir un fonctionnement quasi identique à l'opérateur ternaire du C++ et PHP le fameux :
    S := condition ? true : false;

    mais l'implementation complexe, bien que performante ne sera pas aussi facile à lire qu'un if ou case of.
    donc, on l'oublis.

    l'intérêt a retenir est donc une plus simple implementation, une comprehension plus facile, des performances meilleures, la permission de délocaliser les valeurs ou les comportements (quand il s'agit de procédure).

    exemple avec functions :

    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
     
    type
      TFunc = function (const A, B: integer): integer;
     
    function Add(const A, B: integer): integer;
    begin
      result := A + B;
    end;
     
    function Sub(const A, B: integer): integer;
    begin
      result := A - B;
    end;
     
     
    const
      BTAS : array[boolean] of TFunc = (Add, Sub);
     
    var
      A, B, R : integer;
    begin
      A := 30;
      B := 20;
     
      for R := 0 to 9 do
      begin
        B := BTAS[B < A](A, B);
        A := BTAS[A < B](A, B);
        writeln(A:6,' ',B:6);
      end;
     
      readln;
    end.
    ici l'exemple montre la déclaration intéressante de :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Resultat := BoolArray[condition booléenne](arguments);
    un tableau qui sert de fonction, selon la condition en index!
    c'est pas génial comme concept ?

    et on peut faire la même chose avec un SET ou des entiers. mais la on sort du cadre Booléen.

    bref, le truc c'est surtout d'avoir un moyen rapide et efficace de convertir une condition en un résultat ou comportement différent, avec une implémentation la plus simple et rapide qu'il soit possible de faire.
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

  6. #6
    Membre Expert
    Avatar de Dr.Who
    Inscrit en
    Septembre 2009
    Messages
    980
    Détails du profil
    Informations personnelles :
    Âge : 46

    Informations forums :
    Inscription : Septembre 2009
    Messages : 980
    Par défaut
    assembleur généré pour la méthode du post précédent :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    B := BTAS[B < A](A, B);
    A := BTAS[A < B](A, B);
    2 lignes de codes

    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
     
    cmp ebx,esi
    setnle al
    and eax,$7f
    mov edi,[eax*4+$40c9dc]
    mov edx,esi
    mov eax,ebx
    call edi
    mov esi,eax
    cmp esi,ebx
    setnle al
    and eax,$7f
    mov edi,[eax*4+$40c9dc]
    mov edx,esi
    mov eax,ebx
    call edi
    15 lignes d'assembleur, 52Kc


    assembleur généré par le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    if B < A then
      B := Add(A, B)
    else
      B := Sub(A, B);
     
    if A < B then
      A := Add(A, B)
    else
      B := Sub(A, B);
    8 lignes de codes

    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
     
    cmp ebx,esi
    jle $0040b18d
    mov edx,esi
    mov eax,ebx
    call Add
    mov esi,eax
    jmp $0040b198
    mov edx,esi
    mov eax,ebx
    call Sub
    mov esi,eax
    cmp esi,ebx
    jle $0040b1a7
    mov edx,esi
    mov eax,ebx
    call Add
    jmp $0040b1b0
    mov edx,esi
    mov eax,ebx
    call Sub
    20 lignes d'assembleur, 29Kc


    assembleur généré par le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
      case B < A of
        false : B := Add(A, B);
        true  : B := Sub(A, B);
      end;
      case A < B of
        false : A := Add(A, B);
        true  : A := Sub(A, B);
      end;
    8 lignes de code

    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
     
    cmp ebx,esi
    setnle al
    sub al,$01
    jb $0040b189
    jz $0040b196
    jmp $0040b1a1
    mov edx,esi
    mov eax,ebx
    call Add
    mov esi,eax
    jmp $0040b1a1
    mov edx,esi
    mov eax,ebx
    call Sub
    mov esi,eax
    cmp esi,ebx
    setnle al
    sub al,$01
    jb $0040b1ae
    jz $0040b1b9
    jmp $0040b1c2
    mov edx,esi
    mov eax,ebx
    call Add
    jmp $0040b1c2
    mov edx,esi
    mov eax,ebx
    call Sub
    28 lignes d'assembleur, 34Kc



    on constate donc que la méthode par constante est non seulement plus courte en code pascal et assembleur généré que les autres méthodes.

    a mon grand étonnement, le Case of montre plus d'assembleur que le if.

    on remarque également que le code par constante ressemble beaucoup à celui du case of, a quelques instructions prêt.

    les performances sont par contre étonnante, a croire que ce qui etait performant en D7 ne l'est plus sous D2009.
    la ou on penserai que le IF serai à la ramasse, au contraire, c'est lui qui est le plus rapide sur 1 millions de test : 29 milles cycles.
    contre 34 milles pour le Case of
    et 52 milles pour le tableau booléen...

    à croire que les optimisations sont inefficace sur l'implémentation présentée.


    si l'on test avec des chaines on tombe sur le même verdict :

    if then else : 327 milles cycles
    tableau booléen : 491 milles cycles
    case of : 362 milles cycles

    ils ont vraiment bien améliorer l'optim du if then else, puisque les même tests sous D7 et processeur Intel était moins en faveur de ce dernier contrairement à D2009 sur processeur AMD.

    tout simplement étonant.


    ce qui invalide totalement cette méthode puisqu'elle se montre totalement anti-performante... même si elle montre un concept intéressant mais inéfficace au final.
    j'aurais du tester de suite plutot que de faire confiance aveuglement au dires de mon ami Cirec qui me l'avais montré en 2006.


    tu remarquera cependant, que dans un soucis d'exactitude de mes dires, dés que je dis "cette methode performante" je m'empresse de la tester (si cela n'etait pas déjà fais).
    il est dommage que les tests furent si décevant.
    il faut dire qu'au niveau assembleur, delphi n'est pas encore top top...
    si l'on reprend le code asm et qu'on le modifie correctement on peu donner faveur au tableau boolean...
    mais ce serait contraignant, ce que voulais empécher justement cette methode.
    [ Sources et programmes de Dr.Who | FAQ Delphi | FAQ Pascal | Règlement | Contactez l'équipe ]
    Ma messagerie n'est pas la succursale du forum... merci!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 2
    Dernier message: 09/07/2008, 15h20
  2. Transformer une chaîne de caractères en lien hypertexte
    Par laurentdepibrac dans le forum VBA Access
    Réponses: 4
    Dernier message: 14/05/2008, 10h35
  3. [MySQL] Remplacer une chaîne de caractères d'un champ
    Par hisy dans le forum PHP & Base de données
    Réponses: 5
    Dernier message: 27/03/2007, 13h14
  4. Réponses: 3
    Dernier message: 08/02/2007, 11h55
  5. Réponses: 4
    Dernier message: 24/07/2006, 17h34

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