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 :

Inversion de 8 bits en C


Sujet :

C

  1. #1
    Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2013
    Messages : 5
    Points : 4
    Points
    4
    Par défaut Inversion de 8 bits en C
    bonjour,

    Pourriez-vous m'aider car en effet, je n'arrive pas a créer une permutation sur 8 bits de la manière suivante:

    b7 b6 b5 b4 b3 b2 b1 b0 <- bits initiaux

    b4 b5 b6 b7 b0 b1 b2 b3 <- ordre de bits voulu

    Merci d'avance pour votre aide,

    MilyBass

  2. #2
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Bonjour et bienvenue,

    Il n'y a pas de façon « simple » de le faire (en une seule opération), mais tu peux t'en sortir en quatre étapes avec un ET logique « & », les opérateurs de décalage « << » et « >> » et le OU logique « | ». Tu peux manipuler deux bits à chaque étape.

    Est-ce un devoir scolaire ?

  3. #3
    Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2013
    Messages : 5
    Points : 4
    Points
    4
    Par défaut
    Non, c'est un test.

    Je suis en alternance et sur mon projet j'avais nécessité de faire cette fonction mais mes connaissances sur les masques et le C sont limités.

  4. #4
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 076
    Points : 2 328
    Points
    2 328
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    [...] Il n'y a pas de façon « simple » de le faire (en une seule opération) [...]
    Challenge accepted

    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
    int main(void)
    {
      unsigned char a = 85;
     
      a = ((a & 0x01) << 3) +
          ((a & 0x02) << 1) +
          ((a & 0x04) >> 1) +
          ((a & 0x08) >> 3) +
          ((a & 0x10) << 3) +
          ((a & 0x20) << 1) +
          ((a & 0x40) >> 1) +
          ((a & 0x80) >> 3);
     
      printf ("%d\n", a);
     
      return (0);
    }
    patapay

  5. #5
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Citation Envoyé par MilyBass Voir le message
    Non, c'est un test.

    Je suis en alternance et sur mon projet j'avais nécessité de faire cette fonction mais mes connaissances sur les masques et le C sont limités.
    — Le masque ET te permet de ne conserver que les bits qui sont à 1 dans les deux opérandes et par conséquent, c'est l'équivalent d'une « intersection » mathématique. « 10001000 » en binaire s'écrit 0x88 en hexadécimal. Ainsi « n & 0x88 » est une expression qui ne renvoie que les bits 7 et 4 de n (sans modifier la variable) ;
    — L'opérateur de décalage permet de déplacer les bits d'un registre d'un certain nombre de positions à gauche ou à droite. Donc « n >> 1 » déplace tous les bits de n vers la droite. Attention au signe ! Si n est naturellement non signé, l'opérateur insérera un zéro par la gauche, sinon le bit de poids fort restera intact. En appliquant cet opérateur à l'expression entière ci-dessus (avec des parenthèses si nécessaire), les bits 7 et 4 se retrouvent en position 6 et 3 ;
    — Le masque OU te permet ne conserver que les bits qui sont à 1 dans l'une ou l'autre des opérandes, ou les deux. Par conséquent, c'est l'équivalent d'une « union » mathématique. Tu peux t'en servir pour superposer tous les résultats de tes opérations intermédiaires.

  6. #6
    Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2013
    Messages : 5
    Points : 4
    Points
    4
    Par défaut
    Merci pour ces explications, je vais essayer de partir dans cette direction en procédant de la même manière pour tout les bits

    Mais toutefois, un doute plane: les masques...

  7. #7
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Citation Envoyé par SofEvans Voir le message
    Challenge accepted
    C'est bien ce que je disais : ce n'est pas en une opération, même si le tout tient en une seule expression. Il faut extraire chaque paire de bit et les décaler individuellement (au passage, tu aurais pu utiliser moitié moins de lignes )

    patapay
    C'est surtout que ça ne lui rend pas vraiment service : l'objectif était de l'aider à trouver la solution seule, pas de faire son travail à sa place.

    Citation Envoyé par MilyBass Voir le message
    Merci pour ces explications, je vais essayer de partir dans cette direction en procédant de la même manière pour tout les bits

    Mais toutefois, un doute plane: les masques...
    C'est plus clair avec un schéma :

            001110110010    soit 0x3B2
            ↓↓↓↓↓↓↓↓↓↓↓↓
         &  011011011101    soit 0x6DD
          ---------------
         =  001000010000    soit 0x210
    

    Dans cette opération ET, on compare les bits deux à deux et on ne conserve que ceux qui sont à 1 des deux côtés.

  8. #8
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 076
    Points : 2 328
    Points
    2 328
    Par défaut
    Citation Envoyé par Obsidian Voir le message
    C'est bien ce que je disais : ce n'est pas en une opération, même si le tout tient en une seule expression. Il faut extraire chaque paire de bit et les décaler individuellement (au passage, tu aurais pu utiliser moitié moins de lignes )
    Ah ... J'ai confondu "une seule opération" et "une seule expression".
    Du coup ... je ne vois pas, dans l'état actuelle de mes connaissance, comment on pourrait faire cela en une seule opération.

    Et oui, j'ai fait l'exemple a la va vite sasn reflexion, donc il y avait la place pour faire mieux :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    int main(void)
    {
      unsigned char a = 85;
     
      a = ((a & 0x11) << 3) +
          ((a & 0x22) << 1) +
          ((a & 0x44) >> 1) +
          ((a & 0x88) >> 3);
     
      printf ("%d\n", a);
     
      return (0);
    }
    Citation Envoyé par Obsidian Voir le message
    C'est surtout que ça ne lui rend pas vraiment service : l'objectif était de l'aider à trouver la solution seule, pas de faire son travail à sa place.
    Ben c'est vrai que j'aurai dû écrire ce que tu as écrit juste après mon message pour expliquer ce que j'ai fait, mais au final, tes explications sont très clair et l'exemple que j'ai donné (aussi mauvais soit-il) est finalement comprehensible.

  9. #9
    Modérateur
    Avatar de Obsidian
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Septembre 2007
    Messages
    7 369
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2007
    Messages : 7 369
    Points : 23 623
    Points
    23 623
    Par défaut
    Citation Envoyé par SofEvans Voir le message
    Ben c'est vrai que j'aurai dû écrire ce que tu as écrit juste après mon message pour expliquer ce que j'ai fait, mais au final, tes explications sont très clair et l'exemple que j'ai donné (aussi mauvais soit-il) est finalement comprehensible.
    Ton exemple n'est pas « mauvais » du tout. Cela dit, il aurait été presque parfait si tu avais utilisé des « | » à la place des « + ».

  10. #10
    Membre émérite Avatar de SofEvans
    Homme Profil pro
    Développeur C
    Inscrit en
    Mars 2009
    Messages
    1 076
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur C

    Informations forums :
    Inscription : Mars 2009
    Messages : 1 076
    Points : 2 328
    Points
    2 328
    Par défaut
    ... oui, tant qu'à faire, si on fait des opération sur les bit, autant utiliser ce qu'il faut.

    J'aurai dû utiliser | et non +

  11. #11
    Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2013
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2013
    Messages : 5
    Points : 4
    Points
    4
    Par défaut
    Merci beaucoup votre aide m'a été bénéfique

  12. #12
    Membre expérimenté
    Profil pro
    Développeur en systèmes embarqués retraité
    Inscrit en
    Mars 2006
    Messages
    946
    Détails du profil
    Informations personnelles :
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Mars 2006
    Messages : 946
    Points : 1 351
    Points
    1 351
    Par défaut
    Salut,

    Bon, le PO a eu son déclic, c'est le principal. Pour simplement 8 bits, je créerais une table de conversion et à l'usage on n'utiliserait finalement qu'une opération très rapide. C'est certainement moins beau que de la manipulation de bits, mais on ne pourra pas nier que c'est plus efficace.

    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
    #include <stdio.h>
     
    const unsigned char swapper[]=
    {
        0x00, // 0x00
        0x08, // 0x01
        0x0c, // 0x02
        // .../...
        0xf7, // 0x00
        0xff, // 0xff
    };
     
    int main(void)
    {
        printf("%u\n", swapper[2]);
        return 0;
    }
    Fabriquer la table n'est pas beaucoup plus dur. Pour ça, la manipulation de bits, c'est très bien. Personnellement j'utilise python pour ce genre de travail, mais en C c'est jouable aussi.

    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
    #include <stdio.h>
     
    int main(void)
    {
        int value;
        unsigned char result;
     
        printf("const unsigned char swapper[]=\n{\n");
        for(value=0;value<0x100;value++)
        {
            result = ((value & 0x11) << 3)+((value & 0x22) << 1)+((value & 0x44) >> 1)+((value & 0x88) >> 3);
            if(!(value %8))
               printf("    ");
            printf("0x%02x,", result);
            if(value %8 == 7)
               printf("\n");
        }
        printf("};\n");
        return 0;
    }
    A+

    Pfeuh

  13. #13
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    Moi, ma première idée était de me contenter d'une table de 16.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    unsigned char inverse(unsigned char v)
    {
       static const unsigned char tab [] ={0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
       return tab[v%16]+16*tab[v/16];
    }
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

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

Discussions similaires

  1. Inversion de bits d'un octets
    Par agentchico dans le forum C
    Réponses: 18
    Dernier message: 30/04/2008, 08h40
  2. inverser bits d'un nombre binaire
    Par jojo_ol76 dans le forum MATLAB
    Réponses: 7
    Dernier message: 09/11/2007, 10h05
  3. Cryptage d'un fichier par inversion de bits
    Par Theo190107 dans le forum x86 16-bits
    Réponses: 19
    Dernier message: 31/08/2007, 22h34
  4. Ecrire dans un fichier binaire en inversant les poids des bits
    Par zejo63 dans le forum Entrée/Sortie
    Réponses: 1
    Dernier message: 09/07/2007, 15h11
  5. algorithme inversement de bits
    Par miminou dans le forum C
    Réponses: 8
    Dernier message: 18/11/2005, 19h50

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