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 :

Manipulation de bits


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2014
    Messages
    123
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2014
    Messages : 123
    Par défaut Manipulation de bits
    Bonjour, J'ai un TP à rendre sur la manipulation de bits. Il faut afficher un entier signé sur 32 bits, puis faire une inversion de n bits sur cet entier à partir du numéro p en partant de la droite. Et enfin, il faut faire une permutation circulaire vers la droite de b bits. Je l'ai fini mais je voudrais qu'on me dise si je peux améliorer mon code, et aussi je dois joindre des captures d 'écrans en testant différentes valeurs, j'aurais besoin qu'on me conseille sur les valeurs à tester pour x, p, n et b svp. Merci !

    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
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    /*--- Inclusion des headers ---------------------------------------------------------------------------------------------------------------*/
    #include <stdio.h>
    #include <limits.h> /* pour INT_MIN sur certains compilateurs */
    #include <ctype.h> /* nécessaire pour tolower */
     
     
    /*--- Définition des constantes ------------------------------------------------------------------------------------------------------------*/
    #define TAILLEINT 8*sizeof(int) /*Dans le cas d'un compilateur 64 bits, sizeof(int) = 8 */
     
    /*--- Prototypage des fonctions et des procédures (déclarations) ---------------------------------------------------------------------------*/
    void aff_bits (int x);
    int inverse (int x, int p, int n);
    void soulignement (int x,int p,int n);
    int rot_droite(int x,int b);
     
    /*--- Définition des fonctions et des procédures --------------------------------------------------------------------------------------------*/
    void aff_bits (int x)
    /*=============================================================================================================================================
    Description     : Permet d'afficher un entier signé en binaire sur 32 bits
    Entrée          : entier x entré par l'utilisateur
     
    =============================================================================================================================================*/
    {
        int i;
     
        unsigned int masque = INT_MIN;  /*le masque est non signé pour que ça affiche un 0 et pas un 1 lors du décalage à droite du masque
                                        On Choisit INT_MIN car ça permet de tester le nombre de gauche à droite, en décalant à chaque fois de 1 */
        for (i=0;i<TAILLEINT;i++)
        {
            printf("%d ",((x&masque)?1:0)); /*On utilise l'opérateur & car s'il y a 1&1 ça retourne 1, 1&0 retourne. Alors que 1|0 et 1^0 retourne aussi 1.*/
            masque=(masque >>1);
        }
    }
     
    int inverse (int x, int p, int n)
    /*==============================================================================================================================================
    Description     :   Permet d'inverser les bits sur une zone donnée, on compte p bits à partir de la droite, et on compte n bits vers la droite à partir
                        de cet indice.
    Entrées         :   entier x entré par l'utilisateur
                        entier p entré par l'utilisateur
                        entier n entré par l'utilisateur
    Sortie          :   entier y inversé sur la zone n à partir de p
    =======================================================================================================================================================*/
    {
        int masque=(~(-1<<n))<<(p-n);   /*On choisit le nombre -1 car en binaire il n'y a que des 1, on le décale de n bits vers la gauche pour obtenir un masque
                                        avec que des 1 et des 0 sur la droite sur n bits, puis on fait l'inverse de ce masque pour n'obtenir que des 0 et des 1
                                        uniquement sur n bits, puis on décale ce masque sur la gauche de n-p bits. Ainsi on obtient un masque constitué uniquement
                                        de 1 qui correspond pile à la zone à inverser. */
     
        int y = masque ^ x;            /*1^0=1 et 1^1=0, ce qui permet d'inverser les bits. */
     
        return(y);
    }
     
    void soulignement (int x,int p,int n)
    /*=======================================================================================================================================================
    Description     :   permet de souligner la zone du bit à inverser.
    Entrées         :   entier x entré par l'utilisateur
                        entier p entré par l'utilisateur
                        entier n entré par l'utilisateur
    =========================================================================================================================================================*/
    {
        int i;
        printf("\n");
        for (i=1;i<=TAILLEINT-p;i++) printf("  ");
        for (i=1;i<=n;i++) printf("--");
        printf("\n");
    }
     
    int rot_droite(int x,int b)
    /*=========================================================================================================================================================
    Description     :   permet d'effectuer une permutation circulaire vers la droite de b bits d'un entier x.
    Entrées         :   entier x entré par l'utilisateur
                        entier b correspondant au nombre de bits de rotation
    Sortie          :   entier z permuté vers la droite.
    ===========================================================================================================================================================*/
    {
        int i;
        unsigned int z=x; /* On copie l'entier x dans un entier non signé afin que le décalage vers la droite ne donne pas des 1 dans le cas où il y a un 1 au 32e bit. */
        for(i=1;i<=b;i++) z=((z&1)?((z>>1)|INT_MIN):(z>>1));    /* On choisit de tester avec le chiffre 1 car on va tester le bit le plus à droite. S"il s'agit d'un 0, il
                                                                suffit juste de décaler sur la droite, et un 0 est ajouté à gauche du nombre, s'il s'agit d'un 1, on applique
                                                                | avec INT_MIN car ça va rajouter un 1 sur le bit de poids fort après le décalage. */
     
        return (z);
    }
     
    int main()
    {
        int ok; /* variable qui permet de vérifier qu'on a bien saisi un nombre et non des caractères. */
        int x;  /* nombre entré par l'utilisateur */
        int p;  /* Permet de pointer la zone du bit à inverser */
        int n;  /* Permet d'indiquer le nombre de bits à inverser */
        int y;  /* entier inversé */
        int b;  /* nombre de bits qur lesquels on va effectuer la permutation circulaire */
        int z;  /* entier permuté */
        char rep;   /* variable de réponse pour recommencer le programme */
     
     
        printf("\n\t\tM A N I P U L A T I O N     D E     B I T S\n\t\t-------------------------------------------\n\n");
        do
        {
            do
            {
                printf("Donnez un entier quelconque : ");
                ok = scanf("%d",&x);
                while (getchar()!='\n');
            } while (!ok);
     
            printf("Voici sa representation en binaire :\n");
            aff_bits(x);
            printf("\n\n\n");
            printf("On va inverser n bits de ce nombre a compter du p eme :\n");
     
            do
            {
                printf("Donner p ( > 0 et <= %d) : ",TAILLEINT);
                ok = scanf("%d",&p);
                while (getchar()!='\n');
            } while (!ok && p<=0 && p > TAILLEINT);
     
            do
            {
                printf("Donner n ( > 0 et <= %d) : ",p);
                ok = scanf("%d",&n);
                while (getchar()!='\n');
            } while (!ok && n<=0 && n > p);
     
            y=inverse(x,p,n);
            aff_bits(y);
            soulignement(x,p,n);
     
            printf("\n\nSur le nombre %d de representation binaire :\n",x);
            aff_bits(x);
     
            printf("\nOn va effectuer une permutation circulaire vers la DROITE de b bits.\n");
            do
            {
                printf("Donner b (>0) : ");
                ok = scanf("%d",&b);
                while (getchar()!='\n');
            } while (!ok && b<=0);
     
            z=rot_droite(x,b);
            aff_bits(z);
     
            printf("Recommencer ? (o/n) : ");
            scanf("%c",&rep);
            while (getchar()!='\n');
     
        } while (tolower(rep)!='n');
     
        return 0;
    }

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Le code aurait pu être beau et lisible sans... tes noms de variable.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int x;  /* nombre entré par l'utilisateur */
    int p;  /* Permet de pointer la zone du bit à inverser */
    int n;  /* Permet d'indiquer le nombre de bits à inverser */
    int y;  /* entier inversé */
    int b;  /* nombre de bits qur lesquels on va effectuer la permutation circulaire */
    int z;  /* entier permuté */
    C'est la fête à l'alphabet ? Si tu as plus de 26variables, tu vas les appeler a1,a2, .. ?
    Tu délaisses ton code pendant un temps, tu reviens dessus 1ans après, et là c'est le drame... Malgré les commentaires, tu mets 1h à te remettre dedans car tu ne comprends plus tes variables, ne fait plus facilement le rapprochement.

    Utilise des noms de variables explicite.

    Ensuite, les commentaires.
    C'est bien, c'est beau, c'est compréhensible..
    Seul bémol, sur les commentaires des fonctions..
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Entrées         :   entier x entré par l'utilisateur
                        entier p entré par l'utilisateur
                        entier n entré par l'utilisateur
    " Ok ". Mais concrètement, qu'est ce que x, qu'est ce que p, qu'est ce que n ?
    Explicite les choses : "p pointe vers la zone du bit à inverser" par exemple.
    En l'état, si on prends séparément une de tes fonctions, on ne sait pas ce qu'est x, p, n..


    Ensuite, concernant le code en lui-même...
    Quand tu le compiles, active les warnings ! Il y a plein de jolie chose qui apparaisse...
    warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
    Attention au fait que tu compares des unsigned intavec des int..

    Dans la fonction soulignement().
    warning: unused parameter ‘x’ [-Wunused-parameter]

    Ensuite, tu utilises while (getchar()!='\n');.
    C'est bien, mais améliorable. Tu dois aussi penser à vérifier si tu ne rencontres pas une fin de fichier. --> while ((c=getc()) != '\n' && c != EOF);.

    Sur l'algorithme en lui-même, je ne saurai pas dire, je n'ai pas le temps de m'y plonger complètement.

    Bonne continuation.

  3. #3
    Membre confirmé
    Homme Profil pro
    Lycéen
    Inscrit en
    Avril 2014
    Messages
    123
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Avril 2014
    Messages : 123
    Par défaut
    Bonjour j'ai tenu compte de tes remarques, mais comment on fait pour activer les warnings sur codeblocks ? Quand je compile j'ai 0 warning.

  4. #4
    Membre confirmé
    Homme Profil pro
    Responsable ingénierie des logiciels - Recherche alternance
    Inscrit en
    Novembre 2013
    Messages
    68
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Responsable ingénierie des logiciels - Recherche alternance
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Novembre 2013
    Messages : 68
    Par défaut
    Par défaut ils sont censé être activé ...
    Vérifie si tu n'a pas coché la case "Inhibit all warning messages" dans : Project -> Build Options -> Compiler Flags

Discussions similaires

  1. manipulation de bits d'un byte
    Par orelero dans le forum Langage
    Réponses: 6
    Dernier message: 22/08/2008, 10h41
  2. word_t et Manipulation de bits
    Par fmichael dans le forum C#
    Réponses: 2
    Dernier message: 19/03/2007, 09h33
  3. [VS 2005] Manipuler des bits
    Par b_lob dans le forum C#
    Réponses: 5
    Dernier message: 05/02/2007, 09h51
  4. [Ada] Manipulation de "Bits"
    Par BoBy9 dans le forum Ada
    Réponses: 2
    Dernier message: 14/06/2006, 11h57
  5. Manipulation de bits
    Par Tsly dans le forum C++
    Réponses: 2
    Dernier message: 28/09/2005, 12h41

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