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
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
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
L'algorithme n'a pas été correctement recopié. Tu en trouveras une version fonctionnelle là-bas : https://graphics.stanford.edu/~seand...everseParallel .
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).
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:
La valeur de d- 642514944 value/2= 321257472 étant fausse
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
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
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.
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
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager