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 :

C unleashed chapitre 5


Sujet :

C

  1. #1
    Membre régulier Avatar de J4e8a16n
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    271
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 271
    Points : 119
    Points
    119
    Par défaut C unleashed chapitre 5
    Bonjour à tousm


    Je cheche les Listings de code du chapitre 5 de CUnleashed.

    Ils ne sont pas sur le CD d'accompagnement du livre.


    Amicalement,


    JPDaviau
    Petit Malin
    "accélérateur . . . qui pousse . . . un électron a passer par deux trous d’un écran en même temps." (Cyrille Burt: "C’est mieux qu’un fantôme") (Janus p.251)
    "Joy is to love what is, pain is to love what is not"
    )

    HP Pavilion Elite Desktop PC 570-p0xx - Window10 64 bits - Intel(R) Core(TM)2 Quad CPU Q8200 @ 3GHz x86_64-w64-mingw32-gcc-7.3.0.exe

  2. #2
    Membre régulier Avatar de J4e8a16n
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    271
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 271
    Points : 119
    Points
    119
    Par défaut
    Bonjour à tous,


    Ce code est censé inverser les bits 0xABCDEFGH en 0xHGFEDCBA.


    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
     
    #ifdef __cplusplus
    #error This source file is not C++ but rather C. Please use a C-compiler
    #endif
     
    /*  bit_rev3.c   page 150  */
     
    #include <stdio.h>
    #include <stdlib.h> 
    #define VALUE_BITS (CHAR_BIT * sizeof (unsigned long))
     
     
    unsigned long bit_rev3(unsigned long value)
    {
    printf("%lX\n", value);
     
    value = ((value & 0x55555555)< 1) | ((value >> 1 ) & 0x55555555);
    value = ((value & 0x33333333)< 2) | ((value >> 2 ) & 0x33333333);
    value = ((value & 0x0f0f0f0f)< 4) | ((value >> 4 ) & 0x0f0f0f0f);
    value = ((value & 0x00ff00ff)< 8) | ((value >> 8 ) & 0x00ff00ff);
    value = ((value & 0x0000ffff)< 16) | ((value >> 16 ) & 16);
     
    printf("%lX\n", value);
     
    return value;
     
    }
     
     
     
     
    int main(int argc, char *argv[])
    {
    int i;
    char *endptr;
     
    	for (i=0;i<argc ;i++ )
    			bit_rev3(strtoull(argv[i], &endptr, 10));
     
     
     
    return 0;
    }

    12900 = 0x3264 mais le code n'est pas inversé. Il y a 4 listings de ce genre autour des pages 149... du chapitre 5 de C Unleashed édition 2000.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Another@DESKTOP-8007BEU ~/endian
    $ ./bit_rev3  12900
    0
    1
    3264
    1

    Tous m'ont donné ce genre de demi résultat.

    Le nageur,


    JPDaviau
    Petit Malin
    "accélérateur . . . qui pousse . . . un électron a passer par deux trous d’un écran en même temps." (Cyrille Burt: "C’est mieux qu’un fantôme") (Janus p.251)
    "Joy is to love what is, pain is to love what is not"
    )

    HP Pavilion Elite Desktop PC 570-p0xx - Window10 64 bits - Intel(R) Core(TM)2 Quad CPU Q8200 @ 3GHz x86_64-w64-mingw32-gcc-7.3.0.exe

  3. #3
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    L'algorithme n'a pas été correctement recopié. Tu en trouveras une version fonctionnelle là-bas : https://graphics.stanford.edu/~seand...everseParallel .


    Citation Envoyé par J4e8a16n Voir le message
    Ce code est censé inverser les bits 0xABCDEFGH en 0xHGFEDCBA.
    Ce que tu illustres ne correspond - a priori - pas à une inversion des valeurs des bits, mais à une inversion de celles des demi-octets. Attention également par ailleurs à la confusion : je ne sais pas ce que représentent tes lettres ici mais l'écriture hexadécimale ordinaire n'utilise que jusqu'à la lettre F (soit six symboles de plus qu'en écriture décimale).


    Utilise de préférence des types d'une taille bien définie lorsque tu réalises ce genre d'opération, ça peut t'éviter des surprises. Ici, on remplacera unsigned int / unsigned long par uint32_t (défini dans stdint.h / inttypes.h).

  4. #4
    Membre régulier Avatar de J4e8a16n
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    271
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 271
    Points : 119
    Points
    119
    Par défaut
    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
     
    #ifdef __cplusplus
    #error This source file is not C++ but rather C. Please use a C-compiler
    #endif
     
    /*  bit_rev3.c   page 150  */
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <limits.h>
     
    #define VALUE_BITS (CHAR_BIT * sizeof (unsigned long))
     
    /* 
     
    Ce que tu illustres ne correspond - a priori - pas à une inversion des valeurs des bits, mais à une inversion de
    celles des demi-octets. Attention également par ailleurs à la confusion : je ne sais pas ce que représentent tes
    lettres ici mais l'écriture hexadécimale ordinaire n'utilise que jusqu'à la lettre F (soit six symboles de plus qu'en
    écriture décimale).
     
     
    Utilise de préférence des types d'une taille bien définie lorsque tu réalises ce genre d'opération,
    ça peut t'éviter des surprises. Ici, on remplacera unsigned int / unsigned long 
    par uint32_t (défini dans #include <stdint.h> / #include <inttypes.h>).
     
     
    unsigned int v; // 32-bit word to reverse bit order
     
    // swap odd and even bits
    v = ((v >> 1) & 0x55555555) | ((v & 0x55555555) << 1);
    // swap consecutive pairs
    v = ((v >> 2) & 0x33333333) | ((v & 0x33333333) << 2);
    // swap nibbles ... 
    v = ((v >> 4) & 0x0F0F0F0F) | ((v & 0x0F0F0F0F) << 4);
    // swap bytes
    v = ((v >> 8) & 0x00FF00FF) | ((v & 0x00FF00FF) << 8);
    // swap 2-byte long pairs
    v = ( v >> 16             ) | ( v               << 16); 
    */
     
     
    uint32_t bit_rev3(uint32_t value)
    {
    char hex1[50];
    char hex2[50];
    printf("b- value/2= %d\n", value/2);
    sprintf(hex1, "%x", value);
    printf("c- hex1= %s\n", hex1);
    /*   developpez 
    https://graphics.stanford.edu/~seander/bithacks.html#ReverseParallel
    */
     value = ((value >> 1) & 0x55555555)| ((value & 0x55555555) << 1);
    value = ((value >> 2) & 0x33333333) | ((value & 0x33333333) << 2); 
    value = ((value >> 4) & 0x0F0F0F0F) | ((value & 0x0F0F0F0F) << 4);
    value = ((value >> 8) & 0x00FF00FF) | ((value & 0x00FF00FF) << 8);
    value = ( value >> 16             ) | ( value               << 16);
    /*   unleashed */
    /*   value = ((value & 0x55555555) << 1) | ((value >> 1 ) & 0x55555555);
    value = ((value & 0x33333333) << 2) | ((value >> 2 ) & 0x33333333);
    value = ((value & 0x0f0f0f0f) << 4) | ((value >> 4 ) & 0x0f0f0f0f);
    value = ((value & 0x00ff00ff) << 8) | ((value >> 8 ) & 0x00ff00ff);
    value = ((value & 0x0000ffff) <<16) | ((value >>16 ) & 16); */
     
    sprintf(hex2, "%x", value);
    printf("d- value= %d  value/2= %d\n", value, value/2);
    printf("e- hex2= %s\n", hex2);
     
    return value;
     
    }
     
     
     
     
    int main(int argc, char *argv[])
    {
    int i;
    char hex[50];
     
    	for (i=1;i<argc ;i++ ){
    		sprintf(hex, "%x", atoi(argv[i]));
    		printf("a- hex= %s\n", hex);
    		bit_rev3(atoi(argv[i]));
    	}
     
    return 0;
    }
     
    }

    Résultat:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Another@DESKTOP-8007BEU ~/endian
    $ ./bit_rev3.exe 12900
    a- hex= 3264
    b- value/2= 6450
    c- hex1= 3264
    d- value= 642514944  value/2= 321257472
    e- hex2= 264c0000
    La valeur de d- 642514944 value/2= 321257472 étant fausse

    e- hex2= 264c0000 l'est aussi.


    JPDaviau
    Petit Malin
    "accélérateur . . . qui pousse . . . un électron a passer par deux trous d’un écran en même temps." (Cyrille Burt: "C’est mieux qu’un fantôme") (Janus p.251)
    "Joy is to love what is, pain is to love what is not"
    )

    HP Pavilion Elite Desktop PC 570-p0xx - Window10 64 bits - Intel(R) Core(TM)2 Quad CPU Q8200 @ 3GHz x86_64-w64-mingw32-gcc-7.3.0.exe

  5. #5
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Euh.. 0x264c0000 est bien la valeur que l'on obtient après inversion des 32 bits de 0x00003264.

    On s'en rend compte en implémentant des tests unitaires adéquats, par exemple :

    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
    #include <inttypes.h>
    #include <stdio.h>
    #include <string.h>
     
     
    uint32_t bit_rev3(uint32_t value);
     
     
    const char *hbtos(unsigned int halfbyte) {
        switch (halfbyte) {
            default:
            case 0x0u: return "0000";
            case 0x1u: return "0001";
            case 0x2u: return "0010";
            case 0x3u: return "0011";
            case 0x4u: return "0100";
            case 0x5u: return "0101";
            case 0x6u: return "0110";
            case 0x7u: return "0111";
            case 0x8u: return "1000";
            case 0x9u: return "1001";
            case 0xau: return "1010";
            case 0xbu: return "1011";
            case 0xcu: return "1100";
            case 0xdu: return "1101";
            case 0xeu: return "1110";
            case 0xfu: return "1111";
        }
    }
     
    void tobinary(char *dst, const void *src, size_t size) {
        while (size--) {
            const unsigned int byte = (unsigned int)*((const unsigned char *)src + size);
     
            memcpy(dst, hbtos(byte >>  4u), 4u); //  most-significant half-byte
            dst += 4u;
            memcpy(dst, hbtos(byte & 0xfu), 4u); // least-significant half-byte
            dst += 4u;
        }
    }
     
    size_t writebinary32(FILE *out, uint32_t u) {
        char buf[32u];
        tobinary(buf, &u, sizeof buf / 8u);
        return fwrite(buf, sizeof buf, 1u, out);
    }
     
     
    int main(int argc, char *argv[]) {
        const uint32_t u    = UINT32_C(0x3264),
                       urev = bit_rev3(u);
     
        printf(  "0x%.8" PRIx32 " : ", u);
        writebinary32(stdout, u);
        printf("\n0x%.8" PRIx32 " : ", urev);
        writebinary32(stdout, urev);
        puts("");
     
        return 0;
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    $ ./a.out
    0x00003264 : 00000000000000000011001001100100
    0x264c0000 : 00100110010011000000000000000000

    Note que tu peux directement faire écrire à printf le nombre en hexadécimal, nul besoin d'un buffer intermédiaire.

  6. #6
    Membre régulier Avatar de J4e8a16n
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    271
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 271
    Points : 119
    Points
    119
    Par défaut
    Merci beaucoup.
    Petit Malin
    "accélérateur . . . qui pousse . . . un électron a passer par deux trous d’un écran en même temps." (Cyrille Burt: "C’est mieux qu’un fantôme") (Janus p.251)
    "Joy is to love what is, pain is to love what is not"
    )

    HP Pavilion Elite Desktop PC 570-p0xx - Window10 64 bits - Intel(R) Core(TM)2 Quad CPU Q8200 @ 3GHz x86_64-w64-mingw32-gcc-7.3.0.exe

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

Discussions similaires

  1. Sortie en plusieurs pdf découpés par chapitres
    Par Konrad Florczak dans le forum Mise en forme
    Réponses: 7
    Dernier message: 27/07/2006, 14h38
  2. Au chapitre des conversions.
    Par Gloubi99 dans le forum MFC
    Réponses: 7
    Dernier message: 04/11/2005, 23h32
  3. [XSL] numérotation de chapitres
    Par CoCoZ dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 17/08/2004, 18h52

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