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

C Discussion :

Convertir chiffre binnaire en chaine de caractère


Sujet :

C

  1. #21
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Emmanuel Delahaye
    Il faut regrouper les bits selon la spec.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
       double x = 
                     /* partie entiere (sans le signe) */
                     (tab[i][0] & 0x7F) 
                     /* partie decimale */
                  + ((tab[i][1] >> 4) / 10000.0);
     
       /* on suppose sign = 1 : negatif) */
       if (tab[i][0] & 0x80)
       {
          x *= -1;
       }
       printf ("%.2f\n", x);
    C'est un peu ésotérique. Il faut connaître les opérateurs bits (indispensable en embarqué...)
    Il faut remplacer 100000.0 par 16.0 ou alors j'ai pas bien compris les specs et elles me semblent avoir peu de sens.

    A propos de specs, il y a une différence entre la manière dont Emmanuel a interprété le signe et moi. Peut-être parce que le convertisseur que j'ai utilisé il y a longtemps fonctionnait ainsi, j'ai pris du complément à deux (et j'ai oublié de l'appliquer à la partie fractionnaire, ce qui est un problème); Emmanuel a considéré que c'était grandeur et signe.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  2. #22
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Il faut remplacer 100000.0 par 16.0 ou alors j'ai pas bien compris les specs et elles me semblent avoir peu de sens.
    Ah oui, zut, ce ne sont que des bits et pas des décimaux... Je corrige.

    Merci.
    Pas de Wi-Fi à la maison : CPL

  3. #23
    En attente de confirmation mail
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 249
    Points : 314
    Points
    314
    Par défaut
    pour la partie decimal, ne serait ce pas plus efficace cette methode :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // 625 = 1 + 16 + 32 + 64 + 512
    int partie_apres_virgule(lsb)
    {
     
           if (lsb != 0)
           {
                lsb>=4;
     
                 return (lsb + lsb<<4 + lsb<<1 + lsb<<1 + lsb<<3);
           }
           else{
                  return 0;
           }
    }

    qu'est-ce qui s'execute le plus rapidement ?

    ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return (lsb + lsb<<4 + lsb<<1 + lsb<<1 + lsb<<3);
    ou ça :

  4. #24
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Emcy
    qu'est-ce qui s'execute le plus rapidement ?

    ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return (lsb + lsb<<4 + lsb<<1 + lsb<<1 + lsb<<3);
    ou ça :
    D'abord, je ne comprends pas ta logique de calcul.
    Ensuite, ta décomposition n'est pas celle de 625.
    Enfin, si elle est plus rapide, il y a des chances que le compilateur l'utilise tout seul, ou alors une autre avec des soustractions qui sera plus rapide encore... (15= 16-1 pluôt que 15=1+2+4+8)
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  5. #25
    En attente de confirmation mail
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 249
    Points : 314
    Points
    314
    Par défaut
    voici le raisonnment :

    par exemple, on veut faire lsb x 625 avec lsb = 5

    5 = b 0000 0000 0000 0101
    625 = b 0000 0010 0111 0001

    625 = 1 + 16 + 32 + 64 + 512

    5x1 = 5 = b 0000 0000 0000 0101
    5x16 = 80 = b 0000 0000 0101 0000 (decalage de 4 bit)
    5x32 = 160 = b 0000 0000 1010 0000 (decalage de 1 bit)
    5x64 = 320 = b 0000 0001 0100 0000 (decalage de 1 bit)
    5x512 = 2560 = b 0000 1010 0000 0000 (decalage de 3 bit)

    => 5x625 = 3125

    donc
    return (lsb + lsb<<4 + lsb<<1 + lsb<<1 + lsb<<3);
    equivaut à
    return (lsb*625);


    mais peut-être que c'est plus rapide de faire tout simplement resultat = LSB x 260

  6. #26
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Emcy
    voici le raisonnment:
    Je n'ai toujours pas compris pourquoi tu veux multiplier par 625.

    par exemple, on veut faire lsb x 625 avec lsb = 5

    5 = b 0000 0000 0000 0101
    625 = b 0000 0010 0111 0001

    625 = 1 + 16 + 32 + 64 + 512
    Nous sommes d'accord jusqu'ici (à part que j'aurais utiliser 625 =
    512+128-8+1 qui permet d'avoir un terme en moins)


    5x1 = 5 = b 0000 0000 0000 0101
    5x16 = 80 = b 0000 0000 0101 0000 (decalage de 4 bit)
    5x32 = 160 = b 0000 0000 1010 0000 (decalage de 1 bit)
    C'est ici que tu te trompes, les décalages ne sont pas cumulatifs.

    5x64 = 320 = b 0000 0001 0100 0000 (decalage de 1 bit)
    5x512 = 2560 = b 0000 1010 0000 0000 (decalage de 3 bit)

    => 5x625 = 3125

    donc
    return (lsb + lsb<<4 + lsb<<1 + lsb<<1 + lsb<<3);
    equivaut à
    return (lsb*625);
    Non car les décalages ne sont pas cumulatifs et donc ça équivaut à 29*lsb.

    mais peut-être que c'est plus rapide de faire tout simplement resultat = LSB x 260
    Qu'est-ce que vient faire 260 ici?

    Si la multiplication explicite est trop lente après mesure, tu peux penser
    à faire ce genre d'optimisation. Mais je mesurerais en contexte avant.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  7. #27
    En attente de confirmation mail
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 249
    Points : 314
    Points
    314
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Je n'ai toujours pas compris pourquoi tu veux multiplier par 625.
    => 2^-4 = 0.0625


    Citation Envoyé par Jean-Marc.Bourguet
    C'est ici que tu te trompes, les décalages ne sont pas cumulatifs.
    => donc il faut faire ça : return (lsb + lsb<<4 + lsb<<5 + lsb<<6 + lsb<<9); ?
    => une multiplication par une puissance de 2 équivaut bien à un decalage de bit ?


    Citation Envoyé par Jean-Marc.Bourguet
    Qu'est-ce que vient faire 260 ici?
    => oups, je sais pas ce que j'ai foutu, je voulais mettre 625

  8. #28
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Emcy
    => donc il faut faire ça : return (lsb + lsb<<4 + lsb<<5 + lsb<<6 + lsb<<9); ?
    Oui. Après avoir vérifié que le compilateur ne génère pas du code plus efficace tout seul. Tu peux aussi faire return lsb << 9 + lsb << 7 - lsb << 3 + lsb;

    => une multiplication par une puissance de 2 équivaut bien à un decalage de bit ?
    Oui.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  9. #29
    En attente de confirmation mail
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 249
    Points : 314
    Points
    314
    Par défaut
    d'accord

    et il n"y a pas une solution pour garder en memoire le resultat des decalages pour gagner en rapidité ?

    au lieu de faire un decalage de la variable de 4 puis de 5, faire un decalage de 4, sauvegarer le resultat et faire un decalage de 1

  10. #30
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Emcy
    et il n"y a pas une solution pour garder en memoire le resultat des decalages pour gagner en rapidité ?
    Une variable?
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  11. #31
    En attente de confirmation mail
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 249
    Points : 314
    Points
    314
    Par défaut
    donc tu penses que :
    lsb += lsb<<4;
    lsb += lsb<<1;
    lsb += lsb<<1;
    lsb += lsb<<3;
    return (lsb);

    est plus rapide que :
    return (lsb + lsb<<4 + lsb<<5 + lsb<<6 + lsb<<9);

  12. #32
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Emcy
    donc tu penses que :
    lsb += lsb<<4;
    lsb += lsb<<1;
    lsb += lsb<<1;
    lsb += lsb<<3;
    return (lsb);

    est plus rapide que :
    return (lsb + lsb<<4 + lsb<<5 + lsb<<6 + lsb<<9);
    Ça ne fait pas la même chose

    Quand on parle de perf, il faut mesurer, c'est la seule façon d'être sûr (et encore, il faut réussir à ne pas se planter sur ce qu'on mesure).
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  13. #33
    En attente de confirmation mail
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 249
    Points : 314
    Points
    314
    Par défaut
    c'est vrai

  14. #34
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 369
    Points : 41 519
    Points
    41 519
    Par défaut
    On peut aussi essayer à coup de <<=...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return (lsb + lsb<<=4 + lsb<<=1 + lsb<<=1 + lsb<<=3);
    Malheureusement, je ne sais pas si la norme garantit l'ordre d'évaluation...

    PS: Emcy, ton code "plus rapide?" ne fait pas la même chose que le return...
    SVP, pas de questions techniques par MP. Surtout si je ne vous ai jamais parlé avant.

    "Aw, come on, who would be so stupid as to insert a cast to make an error go away without actually fixing the error?"
    Apparently everyone.
    -- Raymond Chen.
    Traduction obligatoire: "Oh, voyons, qui serait assez stupide pour mettre un cast pour faire disparaitre un message d'erreur sans vraiment corriger l'erreur?" - Apparemment, tout le monde. -- Raymond Chen.

  15. #35
    Rédacteur

    Avatar de gege2061
    Femme Profil pro
    Administrateur de base de données
    Inscrit en
    Juin 2004
    Messages
    5 840
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Administrateur de base de données

    Informations forums :
    Inscription : Juin 2004
    Messages : 5 840
    Points : 11 625
    Points
    11 625
    Par défaut
    Citation Envoyé par Médinoc
    On peut aussi essayer à coup de <<=...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return (lsb + lsb<<=4 + lsb<<=1 + lsb<<=1 + lsb<<3);
    Malheureusement, je ne sais pas si la norme garantit l'ordre d'évaluation...
    Non c'est le même problème qu'avec la préincrémentation, il ne faut pas retrouver le terme des deux cotés de l'opérateur =
    Même si la variable se trouve deux fois du même côté :
    Citation Envoyé par [url=http://gcc.gnu.org/bugs.html#nonbugs_c]GCC non-bugs[/url]
    he following expressions have unpredictable results:

    x[i]=++i
    foo(i,++i)
    i*(++i) /* special case with foo=="operator*" */
    std::cout << i << ++i /* foo(foo(std::cout,i),++i) */

  16. #36
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par gege2061
    Citation Envoyé par Médinoc
    Malheureusement, je ne sais pas si la norme garantit l'ordre d'évaluation...
    Non c'est le même problème qu'avec la préincrémentation, il ne faut pas retrouver le terme des deux cotés de l'opérateur =
    Même si la variable se trouve deux fois du même côté :
    Il y a deux problèmes, et les deux sont présents ici:
    - l'ordre d'évaluation n'est pas spécifié (donc on se sait pas quel argument est évalué en premier). Les seuls opérateurs pour lesquels il y a un ordre spécifié, c'est operator, , &&, || et ?:

    - le moment où les effets de bords ont lieu n'est pas défini (et donc on ne peut même pas espérer avec un résultat "naturel", le résultat peut être vraiment n'importe quoi...)

    En général, la règle c'est "un objet ne peut pas être lu et écrit par une expression sauf si c'est le résultat du même opérateur" (même si en pratique il y a des cas un peu plus complexe qui vont fonctionner).
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  17. #37
    En attente de confirmation mail
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 249
    Points : 314
    Points
    314
    Par défaut
    et avec des parenthèses, ça marche ?
    return ((((((lsb) + (lsb<<=4)) + (lsb<<=1)) + (lsb<<=1)) + (lsb<<3)));

  18. #38
    Expert éminent

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Points : 6 911
    Points
    6 911
    Par défaut
    Citation Envoyé par Emcy
    et avec des parenthèses, ça marche ?
    Non. Les parenthèses permettent de modifier l'associativité, pas l'ordre d'évaluation ni le moment où les effets de bords sont fixés.
    Les MP ne sont pas là pour les questions techniques, les forums sont là pour ça.

  19. #39
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet
    Non. Les parenthèses permettent de modifier l'associativité, pas l'ordre d'évaluation ni le moment où les effets de bords sont fixés.
    Très important, ça. A encadrer...

    Pour les détails, voir 'sequence point' .
    Pas de Wi-Fi à la maison : CPL

  20. #40
    En attente de confirmation mail
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 249
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 249
    Points : 314
    Points
    314
    Par défaut
    au fait c'est quoi l'effet de bord ? j'ai cherché sur google mais les definitions ne sont pas très clair (un exemple ?)

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 3 PremièrePremière 123 DernièreDernière

Discussions similaires

  1. Convertir un entier en chaine de caractères
    Par zuzuu dans le forum Langage
    Réponses: 2
    Dernier message: 06/12/2008, 11h12
  2. Réponses: 11
    Dernier message: 03/09/2008, 10h41
  3. Convertir une variable en chaine de caractères
    Par Sytchev3 dans le forum Langage
    Réponses: 2
    Dernier message: 03/10/2007, 11h48
  4. Réponses: 4
    Dernier message: 16/05/2006, 21h03

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