Décalage circulaire vers la gauche : est-ce correct ?

Le problème exposé dans ce sujet a été résolu.

Bonjour à tous,

J'ai écrit un programme qui est censé effectuer un décalage circulaire vers la gauche de n bits sur un nombre entier non-signé saisi par l'utilisateur en hexadécimal.

Je l'ai testé plusieurs fois avec différents nombres et a priori il fonctionne bien. J'aimerais en être sûr, et si vous avez le temps de me le confirmer ce serait cool !

Voici un exemple d'utilisation.

entier_a_decaler = A2453F0E (10100010 010001001 00111111 00001110)

n_bits_pour_decalage = 8 // On va décaler de 8bits

resultat -> 453F0EA2 (010001001 00111111 00001110 10100010)

Lien pour le tester (compilez et exécutez en cliquant sur les boutons adéquats en haut à gauche) : http://goo.gl/Lz7Jqp

Mon code :

 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
#include <stdio.h>

/*
 * Explications sur le programme.
 *
 * 1. On initialise la variable `val` qui contient l'entier dont les chiffres seront décalés, ainsi que la variable `n_bits` qui contient le nombre de bits à décaler.
 * 2. Décaler n bits équivaut strictement à effectuer n décalages d'un seul bit, une boucle for sera donc utilisée pour faire chacun de ces décalages.
 * 2.1. Au début de la boucle, on stocke dans `tmp` le bit le plus à gauche : ce qui est particulièrement utile s'il vaut 1, car on ne perdra ainsi pas d'information.
 *      Pour le récupérer, on utilise un ET logique.
 * 2.2. Ensuite, on effectue le décalage d'un bit vers la gauche : le bit qui est parti (ie. : le bit qui était le plus à gauche) n'est pas perdu, puisque contenu
 *      dans `tmp`. Un 0 a été inséré automatiquement à droite.
 * 2.3. En fin de boucle, on teste si `tmp` vaut 1. Si c'est le cas, on remplace le bit le plus à droite par 1. Sinon, pas d'opération à effectuer (le 0 ayant été
 *      automatiquement inséré). Cette opération de remplacement se fait grâce à un OU logique.
 * 3. Après la boucle, on affiche `val`, qui contient désormais le nombre issu du décalage circulaire vers la gauche.
 *
 *
 */

int main(){
    unsigned int val = 0; // Scanf appelé pour affectation  A2453F0E
    printf("Saisissez le nombre en hexadécimal (avec ou sans '0x').\n");
    scanf("%x", &val);

    int n_bits = 8; // Décalage de n bits

    int tmp = 0; // tmp stocke le bit le plus à gauche de val. Sa valeur sera mise à jour à chaque tour de boucle

    int i = 0;
    for(i = 0; i < n_bits; i++) {
        // On souhaite stocker en mémoire le bit le plus à gauche
        if ((val & 2147483648) == 0) { // Le bit le plus à gauche vaut forcément 0
            tmp = 0;
        }
        else {
            tmp = 1;
        }

        val <<= 1;

        if(tmp == 1) { // On remplace le dernier bit par tmp (pas besoin si tmp vaut 0, car le décalage aura automatiquement écrit un 0 tout à droite)
            val = val | 1;
        }
    }

    printf("%X", val);

    return 0;
}
+0 -0

Hello,

Le code a l'air correct, mais je pense qu'on pourrait faire mieux (comprendre : plus compréhensible).

Le nombre 2147483648 est asser mystérieux. On sait que c'est un masque, mais on ne sait absolument pas quels bits on garde. L'écriture en hexadecimal est déjà plus clair : 0x80000000 (on voit tout de suite qu'il y a plein de zero et qu'en fait on ne garde qu'un seul bit).
Puisque tu veux tester la valeur du bit de poid fort, tu pourrais même faire : if (val >> 31).

Pour un décalage de n_bits bits, on peut aussi le faire en une ligne : (val << n_bits) | (val >> (32-n_bits)) : on décale vers la gauche ce qu'on veut, et on récupere les bits qui "sortent" en décalant vers la droite de 32-n_bits (en supposant que val a une taille de 32 bits).

Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte