PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Double nach String



luma
18.07.2005, 13:13
Hio. Ich such nach ner smarten und effizienten Lösung wie ich einen Double-Wert in einen String konvertieren kann. Hab die Methode itoa() gefunden... Wie konvertier ich jetzt aber ein Double-Value? Hat mir da vielleicht jemand ne Eigenkonstruktion?

cu
Lutz

PicNick
18.07.2005, 13:40
Schau mal, ob das was für dich ist

Conversion functions for double arguments.
Note that these functions are not located in the default library, libc.a, but in the mathematical library, libm.a. So when linking the application, the -lm option needs to be specified.



#define DTOSTR_ALWAYS_SIGN 0x01
#define DTOSTR_PLUS_SIGN 0x02
#define DTOSTR_UPPERCASE 0x04
char * dtostre (double __val, char *__s, unsigned char __prec, unsigned char __flags)
char * dtostrf (double __val, char __width, char __prec, char *__s)

luma
18.07.2005, 15:08
Naja hilft mir jetzt nur in der Weise, dass ich jetzt weiß, dass es ne Funktion dtostre gibt mit der man doubles konvertieren kann...

Hättest du mir vielleicht ein kleines (vollständiges) Codebeispiel??

PicNick
18.07.2005, 15:59
Ich hab's noch nie verwendet: Ich tät probieren

char cString[24];
double dDouble = 53.55;

dtostre (dDouble, &cString, 3, 0);
// 3 dezimalstellen, VZ nur wenn minus
in cString sollte dann "53.55" stehen

? oder nicht ?

luma
18.07.2005, 16:49
Nee hat leider nicht geklappt... Um meinen Flash meines Asuros zu schonen, hab ich den Code erstmal mit Dev-C++ getestet. Dann kam folgender Linkererror: undefined reference to dtostre. Dann hab ich's mal mit WinAVR compiliert. Da gab's keinen Fehler, dafür haben diese paar Zeilen Code 58 % meines Flashs verschwendet (so das Script avr-sizex). Gibt's da nicht noch ne andere Lösung, so ne Eigenkreation?

Für long/int-Werte hatte ich das gleiche Problem. Ich hab dann im Buch "C von A bis Z" folgenden Code für das umwandeln einer long-Variable in einen String:



char *LongToString(long wert, unsigned int laenge) {
char *ret = (char *) malloc(laenge + 1 * sizeof(char));
int i;

for(i = 0; i < laenge; i++) {
ret[laenge-i-1] = (wert % 10) + 48;
wert = wert / 10;
}
ret[laenge] = '\0';
return ret;
}


Nur verschwendet der Aufruf von malloc() unheimlich viel Flash (> 10 %). Für was braucht man das malloc() überhaupt? Kann diese Funktion nicht auch einfach ein bisschen abändern, damit sie auch double-Werte konvertiert? Wär perfekt, wenn mir jemand zwei Funktionen + Beispiel zu den oben genannten Problemen liefern kann! Ich kenn mich nämlich in C noch nicht so aus und wenn man mal Java kann weiß man was eine wirklich gute Sprache unterscheidet (diese ganzen kryptischen Zeichen unter C bereiten mir Kopfschmerzen! :()...

cu
Lutz

PicNick
18.07.2005, 18:57
Der Format-Spezifier (sprintf, printf, scanf) vom normalen C / C++ ist ein absolutes high-light. Wenn du das nicht hast, ist das ganze mühsam.

Note that these functions are not located in the default library, libc.a, but in the mathematical library, libm.a. So when linking the application, the -lm option needs to be specified.
Das hast du berücksichtigt ?

Aus dem Bauch heraus kann ich dir jetzt nix anbieten. Ich muß mich da schlau machen.

izaseba
18.07.2005, 21:00
Hallo,
Mal folgende Überlegung...
Mußt Du überhaupt mit double rechnen?
man könnte die Zahl mit 100 oder 1000 malnehmen, dann das ganze in ein String umrechnen, und an der entsprechenden Stelle ein Komma setzen ?

Gruß Sebastian

Kjion
18.07.2005, 21:35
Double zu String ist immer sehr Speicherplatzaufwändig mit 8-Bit Controllern. Muss es den unbedingt eine Float Zahl sein ?? Geht es nicht auch mit Integer Werten oder so ??

Die Funktion oben kann man ganze einfach auch ohne malloc() schreiben, man muss einfach eine entsprechend große lokale Variable anlegen. Dynamische Speicherverwaltung ist sowieso meist oversized für AVRs :-)

MfG Kjion

luma
20.07.2005, 13:14
Kjion könntest du mir vielleicht ein Codebeispiel zeigen?

Kjion
20.07.2005, 15:08
Hab einfach mal dein Codestück oben ein bißchen umgeschrieben:



void LongToString(long wert, unsigned int laenge, char* s) {
int i;

for(i = 0; i < laenge; i++) {
s[laenge-i-1] = (wert % 10) + 48;
wert = wert / 10;
}
s[laenge] = '\0';
}

Aufruf dann mit:


char s[10];

long x = 1234567;

LongToString(x, 7, s);


Wenn ich jetzt auf die schnelle nichts übersehen habe, dann sollte das funktionieren. Man könnte das vielleicht noch etwas beschleunigen mit der div() funktion ( siehe avr-libc Doku ).

MfG Kjion

luma
20.07.2005, 17:12
Danke! Werd das jetzt genauer analysieren :D.

luma
22.07.2005, 15:32
Also der Code funktioniert gut, aber nur bei positiven Zahlen. Bei negativen Zahlen kommt nur murks raus, z.Bsp. so: JSH!"QK

skillii
22.07.2005, 19:14
musst halt eine Abfrage einbauen, dürfte kein Problem sein oder?

mfg

PicNick
22.07.2005, 19:16
Das ist wegen der darstellung von negativen. Du mußt voher das Vorzeichen abfragen


if ( x < 0)
{
printf "-"; // minus an den output string vor oder hinten
x *= -1; // in plus Zahl umwandeln
}

jetzt gehts wieder normal weiter