J'essaye de convertir (et arrondir) un double en tableau de caractères sans convertir avec un std :: to_string sur le double en premier. Cependant, je reçois un texte de mémoire aléatoire à la place. Qu'est-ce que je fais mal?
Voici mon code:
double d = 1.0929998;
d = std::round(d * 100) / 100;
char s[sizeof(d)];
std::memcpy(s,&d,sizeof(d));
Résultat:
s: q = × £ pñ?
Valeur prévue:
s: 1.09
Vous traduisez les octets littéraux de votre double
en char
s. La valeur double
est une représentation binaire (généralement quelque chose comme IEEE 754 ), tandis que char
est une représentation binaire d’un caractère (généralement quelque chose basé sur ASCII ). Ces deux ne sont pas compatibles.
Malheureusement, cela signifie que vous devez suivre un processus de conversion. Soit la std::to_string()
que vous avez dit ne pas vouloir faire, soit un std::stringbuf
plus compliqué (qui appellera quand même std::to_string()
sous le capot)
Vous copiez une double
(qui est une représentation binaire d'un nombre) dans un tableau char
; il n'y a aucune raison pour que ces octets correspondent aux caractères numériques.
Si vous voulez convertir manuellement sans utiliser to_string
, vous devrez extraire les chiffres un à un. Un double n'est pas stocké en mémoire sous forme de jeu de caractères. Vous ne pouvez donc pas simplement copier la mémoire en espérant que tout fonctionne. (pour plus d'informations sur l'interprétation des doubles, voir ici ).
Juste fais ceci premier:
std::ostringstream strs;
strs << dbl;
std::string str = strs.str();
Ceci convertit une double dbl
en une chaîne str
.
Ensuite, vous pouvez le convertir en un tableau de caractères comme celui-ci:
char *cstr = new char[str.length()+1];
str.copy(cstr, str.length());
cstr[str.length()] = '\0';
// use cstr as needed...
delete[] cstr;
Ou simplement ceci:
const char *cstr = str.c_str();
// use cstr as needed...
Ceci n’a pas été testé mais vous pouvez essayer:
std::string to_string(double x)
{
std::ostringstream ss;
ss << x;
return ss.str();
}
Vous pouvez ensuite mettre les caractères de la chaîne retournée dans un tableau de caractères comme ceci:
std::string str = to_string(doubleValue);
char digits[str.length()];
Et puis, grâce au commentaire de Rémy Lebeau, vous pouvez faire ceci:
std::strncpy(digits, to_string(doubleValue).c_str(), sizeof(digits))
ou ca:
to_string(doubleValue).copy(digits, sizeof(digits))
Le processus de conversion par vous-même sans utiliser to_string
peut être le suivant:
char* to_char_array(double num_double, int decimal_place)
{
int num_int = std::round(num_double * pow(10, decimal_place));
int sign = num_int < 0 ? 1 : 0;
num_int = abs(num_int);
if (num_int == 0)
{
char* s = (char*)malloc(decimal_place + 3);
s[0] = '0';
s[1] = '.';
for (int i = 2; i < decimal_place + 2; i++)
s[i] = '0';
s[decimal_place + 2] = '\0';
return s;
}
int digit_count = 1;
int n = num_int;
if (n >= 100000000) { digit_count += 8; n /= 100000000; }
if (n >= 10000) { digit_count += 4; n /= 10000; }
if (n >= 100) { digit_count += 2; n /= 100; }
if (n >= 10) { digit_count++; }
int size = digit_count + 1 + (decimal_place > 0 ? 1 : 0) + sign;
char* s = (char*)malloc(size);
for (int i = 0, integer = num_int; integer != 0; integer /= 10) {
s[size - 2 - i++] = integer % 10 + 48;
if (decimal_place > 0 && i == decimal_place)
s[size - 2 - i++] = '.';
}
s[size - 1] = '\0';
if (sign)
s[0] = '-';
return s;
}
void main()
{
double d = -12.268904;
char* s = to_char_array(d, 3);
cout << "double: " << d << " - char array: " << s << endl;
system("pause");
}