bonjour,
je veut convertir une chaine contenant un hex en FLOAT,
j'ai essayer strtod(str,NULL) mais ça donne pas la valeur désirée
Exemple :
"0X21A3B50A"
ça donne un nombre sans virgule :(
le même résultat je l'obtient avec atoi
merci
Version imprimable
bonjour,
je veut convertir une chaine contenant un hex en FLOAT,
j'ai essayer strtod(str,NULL) mais ça donne pas la valeur désirée
Exemple :
"0X21A3B50A"
ça donne un nombre sans virgule :(
le même résultat je l'obtient avec atoi
merci
0X21A3B50A n'est pas l'expression valide d'un flottant, mais d'un entier. Il faut donc tout d'abord convertir la chaîne "0X21A3B50A" en entier avec strol, strtoul ou sscanf par exemple ensuite caster cet entier en flottant. En même temps je ne comprends pas l'intérêt de faire cette conversion, que cherches-tu à faire exactement ?
Si "0X21A3B50A" est la représentation binaire de ton flottant en chaine de caractères, tu dois convertir cette chaine (représentation BCD) en décimal et pointer ton flottant sur le résultat en décimal.
En gros : (non testé, attention au little endian et big endian)
C'est très moche :aie:, mais c'est pour montrer le principe. Il faut penser : réprésentation en mémoire du flottant.Code:
1
2
3
4
5
6
7
8 char nbStr[] = "0X21A3B50A"; char numChar[4]; numChar[3] = (char)atoi(nbStr[1]); // nbStr[0] etant "0x" numChar[2] = (char)atoi(nbStr[2]); numChar[1] = (char)atoi(nbStr[3]); numChar[0] = (char)atoi(nbStr[4]); float *res = (float *)numChar;
merci :D
Et même en remplaçant tous les nbStr[i] en nbStr[i] + i ça ne marche toujours pas. Pire, ça ne donne même pas le code BCD recherché, qui n'a déjà rien à voir avec la représentation des flottants en C.Citation:
Envoyé par diogene
serialC : relis mon message plus haut. Tu as quelques exemples de conversion des chaînes ici si c'est ce dont tu as besoin.
Ok, mon code est faux, mais le principe peut-être bon.
C'est plus :
Ne sachant pas comment "0X21A3B50A" a été stocké, on ne peut faire que des hypothèses.Code:
1
2
3
4
5
6 char tmp[3]; strncpy(tmp, nbStr[2], 2); tmp[2]= '\0'; numChar[3] = (char)atoi(tmp); strncpy(tmp, nbStr[4], 2); ...
PS : j'ai aussi pensé au BCD.
Dans ce cas fallait mettre du pseudocode car quand tu postes un code C, il est censé marcher.Citation:
Envoyé par fregolo52
Par ailleurs, ça ne marche toujours pas parce que atoi suppose que la chaîne passée en paramètre représente un entier écrit en base 10 et non en base 16.
Et enfin, même si on remplaçait atoi par une fonction atoi16 qui ferait ce que tu veux faire, ton code ne donne toujours pas le bon résultat, et on est même encore loin de l'avoir. Ca serait bien aussi si tu testais un peu tes codes avant de les poster.
voila une proposition
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
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172 loat float_value(char * str) { //32bits ex: 43644935 int test = 0; float retval = 1; int p=0; int i; int j; float m = 0; char * bin; bin = malloc(sizeof(char)*33); for(i=0; i<8; i++) { switch(str[i]) { case '0' : for(j=0; j<4; j++) bin[(i*4) + j]='0' ; break; case '1' : for(j=0; j<3; j++) bin[(i*4) + j]='0'; bin[(i*4) + 3] ='1'; break; case '2' : bin[(i*4) + 0] ='0'; bin[(i*4) + 1] ='0'; bin[(i*4) + 2] ='1'; bin[(i*4) + 3] ='0'; break; case '3' : bin[(i*4) + 0] ='0'; bin[(i*4) + 1] ='0'; bin[(i*4) + 2] ='1'; bin[(i*4) + 3] ='1'; break; case '4' : bin[(i*4) + 0] ='0'; bin[(i*4) + 1] ='1'; bin[(i*4) + 2] ='0'; bin[(i*4) + 3] ='0'; break; case '5' : bin[(i*4) + 0] ='0'; bin[(i*4) + 1] ='1'; bin[(i*4) + 2] ='0'; bin[(i*4) + 3] ='1'; break; case '6' : bin[(i*4) + 0] ='0'; bin[(i*4) + 1] ='1'; bin[(i*4) + 2] ='1'; bin[(i*4) + 3] ='0'; break; case '7' : bin[(i*4) + 0] ='0'; bin[(i*4) + 1] ='1'; bin[(i*4) + 2] ='1'; bin[(i*4) + 3] ='1'; break; case '8' : bin[(i*4) + 0] ='1'; bin[(i*4) + 1] ='0'; bin[(i*4) + 2] ='0'; bin[(i*4) + 3] ='0'; break; case '9' : bin[(i*4) + 0] ='1'; bin[(i*4) + 1] ='0'; bin[(i*4) + 2] ='0'; bin[(i*4) + 3] ='1'; break; case 'A' : bin[(i*4) + 0] ='1'; bin[(i*4) + 1] ='0'; bin[(i*4) + 2] ='1'; bin[(i*4) + 3] ='0'; break; case 'B' : bin[(i*4) + 0] ='1'; bin[(i*4) + 1] ='0'; bin[(i*4) + 2] ='1'; bin[(i*4) + 3] ='1'; break; case 'C' : bin[(i*4) + 0] ='1'; bin[(i*4) + 1] ='1'; bin[(i*4) + 2] ='0'; bin[(i*4) + 3] ='0'; break; case 'D' : bin[(i*4) + 0] ='1'; bin[(i*4) + 1] ='1'; bin[(i*4) + 2] ='0'; bin[(i*4) + 3] ='1'; break; case 'E' : bin[(i*4) + 0] ='1'; bin[(i*4) + 1] ='1'; bin[(i*4) + 2] ='1'; bin[(i*4) + 3] ='0'; break; case 'F' : bin[(i*4) + 0] ='1'; bin[(i*4) + 1] ='1'; bin[(i*4) + 2] ='1'; bin[(i*4) + 3] ='1'; break; } } bin[32] = '\0'; for(i=0;i<9;i++) { if(bin[i] == '1') test = 1; } if (test == 0) return 0; int w; for(i=0; i<8; i++) { w=1; for(j=0;j<7-i;j++) w=w*2; if(bin[i+1]=='1') p = p + w; } p -= 127; float x; for(i=0; i<23; i++) { x=1; for(j=0;j<i+1;j++) x = x/2; if (bin[i+9]=='1') m = m + x; } m = m + 1; if (bin[0] == '1') retval = -1; float s; s=1; if (p>0) { for(j=0;j<p;j++) s = s * 2; } else if (p<0) { p = p * (-1); for(j=0;j<p;j++) s = s / 2; } retval = (retval * m) * s; free(bin); return retval; }
Ah, tu veux en fait interpréter une chaîne de caractères comme s'il s'agissait de la représentation hexadécimale d'un float. Voici la version que je te propose (inclure stdlib.h) :
Tu choisis celle que tu préfères. J'ai utilisé les mêmes hypothèses que toi, à savoir que int et float ont la même taille, que les float sont représentés dans le format ieee 754 et enfin, que str est supposée toujours être une chaîne valide.Code:
1
2
3
4
5 float float_from_hex(const char * str) { int n = strtoul(str, NULL, 16); return *((float *)&n); }
Merci Melem