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 :

rotation de bits


Sujet :

C

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 42
    Par défaut rotation de bits
    Bonjour a tous,
    Est ce que quelqu'un sais si il est possible de faire une rotation de bits sur une valeur quelconque, en C.
    Attention, je parle pas du decalage classique avec les operateurs << et >>, mais une rotation, cad qu'en plus de decaler, il faut reinjecter les bits sortant de l'autre cote, exemple:

    0x0001 si rotation a droite, devient: 0x8000

    Une instruction assembleur (le ROR/ROL) nous permet de faire ca, mais j'arrive pas a l'utiliser!! (voir forum assembleur)

  2. #2
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2006
    Messages : 138
    Par défaut
    Citation Envoyé par pierabobl
    0x0001 si rotation a droite, devient: 0x8000
    Quand tu fais une rotation je ne vois pas comment tu peux faire pour passer de 0x0001 à 0x8000.

    ce serais plus logique que 0x0001 devienne 0xF000.

    La représentation la plus simple pour les rotations reste le binaire:

    tu veux passer de :

    00 00 01 01 à 10 00 00 10

    le ROR et le ROL doivent avoir une correspondance en C j'investigue ...

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2006
    Messages : 138
    Par défaut
    Je pense que pour la rotation vers la gauche tu devra te servir des décalages simple avec les retenues.

    retenues ou overflow comme tu préfère (mais je ne me souviens plus trop du fopnctionnement de l'overflow et de sa mise en pratique )

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2006
    Messages : 138
    Par défaut
    Il faut bien faire attention aux mots que tu utilise . Dans ton intitulé tu parle de rotation de bits et dans ton exemple il est question d'hexadecimal....

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 42
    Par défaut rotation de bits
    Ok, je vais essayer d'etre plus clair.

    en binaire, la rotation droite d'un octet 0000 0001 donnerait:
    1000 0000

    en pratique j'aurais plutot besoin d'un mot de plusieurs octet c'est pour ca que je l'ai mit en hexa

  6. #6
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par pierabobl
    Est ce que quelqu'un sais si il est possible de faire une rotation de bits sur une valeur quelconque, en C.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    unsigned rotate_right(unsigned x, int count)
    {
        // assume unsigned has no padding bits
        int const unsigned_bit_count = CHAR_BIT * sizeof unsigned;
        count %= unsigned_bit_count;
        if (count < 0)
            count += unsigned_bit_count;
        // but don't assume anything about << unsigned_bit_count
        if (count == 0)
            return x;
        else
            return (x >> count) | (x << unsigned_bit_count-count);
    }

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2006
    Messages : 138
    Par défaut
    A ce moment la si tu veux faire des rotation sur des octets utilise des word et fais comme indiqué ci dessus.

    C'est à dire tu as un octet genre en Hexa 0xA5

    Donc 0xA5 ca donne en binaire 1010 0101

    Tu veux faire une rotation vers la gauche.
    tu mets ton octet dans un word (initialisé à zero).

    Ca donne 0000 0000 1010 0101.

    Tu fais des décalages simples à gauche et si tu as quelque chose de la forme :

    0000 0001 0100 1010 tu ajoute un cela te donne une rotation vers la gauche.

    tu peux utiliser ce procédé pour les rotations à droite en mettant ton octet dans le poids fort d'un word

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    138
    Détails du profil
    Informations personnelles :
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Mai 2006
    Messages : 138
    Par défaut
    Sorry Jean-Marc à poster avant, j'avais pas vu.

  9. #9
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 42
    Par défaut rotation de Bits
    Merci merci.

    Je vais essayer ca.

    Je suis tout de meme un peu decu de pas pouvoir utiliser une seule instruction...

    ca remet en cause tous l'interet du programme. (qui doit avant tout etre rapide)

    pourquoi toujours + vite ...

  10. #10
    CGi
    CGi est déconnecté
    Expert confirmé
    Avatar de CGi
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 061
    Détails du profil
    Informations personnelles :
    Localisation : France, Allier (Auvergne)

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 061
    Par défaut
    Si tu n'as pas de contraite de portabilité tu peux peut-être utiliser l'assembleur directement ça sera probablement plus rapide dans ce cas là.

    Par exemple :
    pour des unsigned char
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    unsigned char rotate_right(unsigned char x, size_t count)
    {
        asm {
             MOV ECX,count
             MOV AL,x
             ROR AL,CL
         }
    }
    pour des unsigned int

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    unsigned rotate_right(unsigned x, size_t count)
    {
        asm {
             MOV ECX,count
             MOV EAX,x
             ROR EAX,CL
           }
    }
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  11. #11
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par fveysseire
    Quand tu fais une rotation je ne vois pas comment tu peux faire pour passer de 0x0001 à 0x8000.

    ce serais plus logique que 0x0001 devienne 0xF000.
    Et par quel miracle ?

  12. #12
    Membre Expert
    Avatar de Pragmateek
    Homme Profil pro
    Formateur expert .Net/C#
    Inscrit en
    Mars 2006
    Messages
    2 635
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Formateur expert .Net/C#
    Secteur : Conseil

    Informations forums :
    Inscription : Mars 2006
    Messages : 2 635
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return (x >> count) | (x << unsigned_bit_count-count);
    Est-ce que le standard garantit que les opérandes de "|" sont complètement évalués avant l'opération "|", évitant des effets de bord gênant?

  13. #13
    Membre chevronné
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 464
    Par défaut
    Citation Envoyé par seriousme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return (x >> count) | (x << unsigned_bit_count-count);
    Est-ce que le standard garantit que les opérandes de "|" sont complètement évalués avant l'opération "|", évitant des effets de bord gênant?
    Je ne suis pas sûr de comprendre la question, mais il y aura problème si les décalages demandés sont négatifs, supérieurs à 31 sur une architecture 32-bit ou supérieurs à 63 sur une architecture 64-bit. Dans ces cas, les résultats des décalages sont à priori indéterminés.

  14. #14
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par seriousme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return (x >> count) | (x << unsigned_bit_count-count);
    Est-ce que le standard garantit que les opérandes de "|" sont complètement évalués avant l'opération "|",
    Oui.

    évitant des effets de bord gênant?
    Quels effets de bord?

  15. #15
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par rigobert
    Je ne suis pas sûr de comprendre la question, mais il y aura problème si les décalages demandés sont négatifs, supérieurs à 31 sur une architecture 32-bit ou supérieurs à 63 sur une architecture 64-bit. Dans ces cas, les résultats des décalages sont à priori indéterminés.
    Et comment veux-tu avoir de tels decalages avec la maniere dont je les calcule?

  16. #16
    Membre chevronné
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 464
    Par défaut
    Citation Envoyé par pierabobl
    Merci merci.

    Je vais essayer ca.

    Je suis tout de meme un peu decu de pas pouvoir utiliser une seule instruction...

    ca remet en cause tous l'interet du programme. (qui doit avant tout etre rapide)

    pourquoi toujours + vite ...
    C'est en effet une petite lacune du C, alors que la plupart des processeurs implémentent le ROR et le ROL depuis bien longtemps (déjà à l'époque des cpu 8-bit...).
    Il n'y a hélas pas de solution idéale pour pallier à ce manque si on veut à la fois un code rapide et portable.
    Et même si la portabilité n'est pas cruciale, attention: l'assembleur en ligne n'est pas toujours plus rapide que du code compilé (problème de la discontinuité de l'environnement de l'optimiseur).

  17. #17
    CGi
    CGi est déconnecté
    Expert confirmé
    Avatar de CGi
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 061
    Détails du profil
    Informations personnelles :
    Localisation : France, Allier (Auvergne)

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 061
    Par défaut
    Citation Envoyé par rigobert
    attention: l'assembleur en ligne n'est pas toujours plus rapide que du code compilé (problème de la discontinuité de l'environnement de l'optimiseur).
    Effectivement, mais dans ce cas il y en a une.
    Je viens de tester sur une boucle executé 10000000 de fois

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    unsigned rotate_right_2(unsigned x, int count)
    {
        // assume unsigned has no padding bits
        int const unsigned_bit_count = CHAR_BIT * sizeof(unsigned);
        count %= unsigned_bit_count;
        if (count < 0)
            count += unsigned_bit_count;
        // but don't assume anything about << unsigned_bit_count
        if (count == 0)
            return x;
        else
            return (x >> count) | (x << unsigned_bit_count-count);
    }
    temps = 400ms



    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    unsigned rotate_right(unsigned x, size_t count)
    {
        asm {
             MOV ECX,count
             MOV EAX,x
             ROR EAX,CL
           }
    }
    temps = 70ms

    (Sur un P4 2GHz)
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  18. #18
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Il ne faut quand même pas trops sous-estimer les compilateurs. Si on admet un comportement non spécifié, compiler ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    unsigned rotate_right(unsigned x, size_t count)
    {
      int const unsigned_bit_count = CHAR_BIT * sizeof(unsigned);
      return (x >> count) | (x << unsigned_bit_count-count);
    }
    avec gcc 2.95 (la plus vieille version que j'ai) donne:
    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
    	.file	"rot.c"
    	.version	"01.01"
    gcc2_compiled.:
    .text
    	.align 16
    .globl rotate_right
    	.type	 rotate_right,@function
    rotate_right:
    	movl 8(%esp),%ecx
    	movl 4(%esp),%eax
    	rorl %cl,%eax
    	ret
    .Lfe1:
    	.size	 rotate_right,.Lfe1-rotate_right
    	.ident	"GCC: (GNU) 2.95.4 20011002 (Debian prerelease)"

  19. #19
    mat.M
    Invité(e)
    Par défaut
    Excepté la solution de CGI je ne vois pas autrement; peut- être avec des champs de bit...
    Mais il faut faire tout un traitement avec des champs de bits..

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par pierabobl
    Est ce que quelqu'un sais si il est possible de faire une rotation de bits sur une valeur quelconque, en C.
    Oui, mais pas directement. Il faut sauvegarder le bit qui va être ejecté faire le décalage et le réintroduire à la main...

    OK, c'est pas terrible, mais en version portable, y'a pas mieux (peut être qu'un compilateur très malin detecterait la manoeuvre et mettra un ROL ou ROR...).

    Evidemment, tu peux mettre de l'assembleur en ligne, mais je n'ai rien dit...

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

Discussions similaires

  1. [Binaire] Opérateurs de rotation dee bits ?
    Par Tifauv' dans le forum C
    Réponses: 3
    Dernier message: 09/11/2017, 11h29
  2. Rotation de bits avec Delphi.
    Par fred61 dans le forum Débuter
    Réponses: 7
    Dernier message: 25/05/2011, 12h57
  3. Comment faire une rotation des bits vers la droite ?
    Par Jean-Marc.Bourguet dans le forum Télécharger
    Réponses: 0
    Dernier message: 30/11/2010, 17h12
  4. Rotation de bits d'un char.
    Par fred61 dans le forum Débuter
    Réponses: 5
    Dernier message: 07/08/2009, 15h17
  5. [Free Pascal] Rotation de bits
    Par bubulemaster dans le forum Free Pascal
    Réponses: 2
    Dernier message: 26/12/2007, 13h56

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