Forum Programmation.c Comment effectué une rotation de bit sur un Byte ?

Posté par  .
Étiquettes : aucune
0
18
juin
2005
Je voudrais transformer le byte suivant:
ABCD EFGH
en HGFE DCBA
Les lettres étant des bits bien attendu

Je ne trouve pas de fonction dans la biblio std qui fasse cette op. Et je ne tropuve pas comment la programmé moi même.

Quelqu'un pourait-il m'aidé ?

Merçi d'av,

Julien.
  • # Re...

    Posté par  (site web personnel) . Évalué à 2.

    Je ne peux t'aider directement mais il me semble que ca s'appele changer le bit de poid fort...
  • # premier jet

    Posté par  . Évalué à 3.

    Bonjour
    ca devrait marcher ca

    unsigned char reverse(unsigned char byte)
    {
    int i=0;
    unsigned char temp=0;
    for(i=0;i<7;i++)
    {
    temp+=(((byte>>(7-i))&1)<<i)

    }
    return temp;
    }
    • [^] # Re: premier jet

      Posté par  . Évalué à 2.

      Je vote pour ta solution, au moins côté efficacité : pas de test donc pas de rupture de séquence. Les processeurs apprécient ;-)
      (J'étais en train de préparer ma réponse quand la tienne a été enregistrée, sans doute)
      • [^] # Re: premier jet

        Posté par  . Évalué à 5.

        pas de test donc pas de rupture de séquence.


        et le i < 7 dans le for ?
    • [^] # Re: premier jet

      Posté par  . Évalué à 2.

      je crois que je me suis gourré c'est
      i<8 et pas i<7
  • # Essai

    Posté par  . Évalué à 4.

    unsigned char reverse_char(unsigned char fc)
    {
        unsigned char lRet = 0;
        unsigned char lUMask = 1, lDMask = 1 << 7;
        for ( ; lDmask != 0 ; lDMask >> 1, lUMask << 1 )
            if ( (fc & lDMask) != 0 ) lRet |= lUMask;
        return lRet;
    }
    
    Pour les intégristes du clan d'en face, retirer les "!= 0" et les préfixes des identificateurs ;-) Sinon google reverse_byte donne des solutions ...
  • # Autres solutions

    Posté par  . Évalué à 1.

    La fonction reverse doit fonctionner mieux que la solution proposee precedemment. Tous les processeurs n'ont pas forcement d'instructions pour faire un decalage de plusieurs positions (a gauche ou a droite).

    Par contre j'ai aucune idee des performances de la fonction reverse2, j'ai juste trouve que c'etait marrant.

    unsigned char reverse (unsigned char x)
    {
    int i;
    unsigned char r = 0;
    for (i = 0; i < 8; i++) {
    r = (r << 1) | (x & 1);
    x >>= 1;
    }
    return(r);
    }

    unsigned char reverse2 (unsigned char x)
    {
    unsigned char rev[] = { 0x00, 0x80, 0x00, 0x40, 0x00, 0x20, 0x00, 0x10,
    0x00, 0x08, 0x00, 0x04, 0x00, 0x02, 0x00, 0x01 };
    int i;
    unsigned char r = 0;
    for (i = 0; i < 16; i += 2) {
    r |= rev[i + (x & 1)];
    x >>= 1;
    }
    return(r);
    }

    main()
    {
    int i;
    printf("reverse:\n");
    for (i = 0; i < 8; i++) {
    unsigned char x = 1 << i;
    printf("%02x -> %02x\n", x, reverse(x));
    }

    printf("reverse2:\n");
    for (i = 0; i < 8; i++) {
    unsigned char x = 1 << i;
    printf("%02x -> %02x\n", x, reverse2(x));
    }
    }
    • [^] # Re: Autres solutions

      Posté par  . Évalué à 3.

      Pour choisir parmi les nombreuses méthodes possibles, il faut savoir de quoi tu as le plus besoin.

      - si c'est la rapidité, alors il vaut mieux faire une LUT de 256 valeurs, c'est encore ce qui s'exécutera le plus vite. Par contre ca consomme un peu plus de mémoire (ca peut avoir son importance sur un petit CPU embarqué).

      - si c'est la simplicité, et la taille de code (en mémoire) qui est recherchée, la méthode par décalage est très bien.

      - certains CPU ont des instructions assembleur SWAP concues pour ca. Par contre, adieu la portabilité de ton code.

      - si on a une vraie rotation de bits (pas juste un décalage avec perte du bit qui dépasse, mais généralement ca va nous ramener aussi à de l'assembleur) on peut faire ce genre de choses :

      #define reverse_byte (byte) \
      (((byte<<1)&0x11) \
      | ((byte<<3)&0x22) \
      | ((byte>>3)&0x44) \
      | ((byte>>1)&0x88))

      Si on décompose, ca fait :
      000E 000A
      H000 D000
      00F0 00B0
      0G00 0C00
      -----------------
      HGFE DCBA

      Avantages : aucun test, aucune boucle, et on traite 2 bits à chaque fois.
      Inconvénients : les constantes (mais sur un RISC elles sont mises avec l'instruction), la rotation qui n'est pas équivalente au décalage en C

      Plus d'infos ici :
      http://www.sxlist.com/techref/microchip/math/bit/revbits.htm(...)

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.