Hallo erstmal, ich weiß ja nicht ob ihr es schon wußtet... (oder so
ähnlich)...
... dass der SDCC (ohne neucompilierung der LIB's) mittels PrintF keine
Gleitkommazahlen ausgeben kann !
(okay, ihr wußtet das schon).
Ich mußte wieder mal ein Meß-Steuergerät aufbauen und war wieder
angewiesen darauf, auch Kommazahlen ausgeben zu können. Hatte ich beim
letzten Projekt noch mit Long-Variablen hantiert, bei der jeder Messwert
einfach 10 mal größer erfasst wurde als er war und dann bei der Ausgabe
einfach ein Komma eingefügt wurde, funktionierte das dieses mal nicht
mehr !
Printf und SDCC in Verbindung mit Float ... will nicht !
Außerdem hatte ich erhebliche Speicherplatzprobleme (das Programm mußte
in einem 89S52 laufen).
Also hab ich mir eine eigene Float-to-Ascii Umwandlung gemacht, die
nicht sonderlich schön ausgefallen ist (aber für dieses Projekt
funktioniert hat).
Dabei ist mir ein Bug im SDCC aufgefallen der da heißt:
Beinhaltet eine Float-Variable eine große Zahl, wird diese große Zahl
(ohne Nachkommateil) einer Long-Variable nicht korrekt zugeordnet...
LEIDER muß ich da nur sagen, weil mein ganzer Ansatz für meine eigene
ftoa-Funktion damit hinüber war.
Ich hab das hier gemacht, aber sicherlich hat doch jemand schon mal was
besseres getan als das und würde mir sehr gut gefallen, wenn hier jemand
sine Routine posten würde, damit ich das nächste mal dann eben "was
besseres" habe ! schmunzel wenn niemand was besseres hat, ist
vielleicht der eine oder andere froh drum, wenn er wenigstens das hier
dann hat!
Gruß,
Ralph
------------------------------------------------------------------------
void my_ftoa(float zahl, char *str, char nk)
/* Konvertiert einen Float in einen String mit der Anzahl <nk> an
Nachkommastellen ! Function wird notwendig, da der SDCC in
Standardkonfiguration kein %f innerhalb von <printf> zur Verfügung
stellt.
Die aufgeteilte und"umständliche" Handhabung bei der Zuweisung des
Floats in 2 Longint-Variablen war notwendig, weil der SDCC Compiler
hier einen BUG hat:
Float-Zahlen die größer als 32767 sind (15 Bit signed) werden von
Float nach Long (32 Bit !!!!) nicht korrekt umgesetzt !
Benötigt Bibliothek <string.h>
*/
{
bit b= 0;
bit first;
char *hptr;
signed long divisor,gz1,gz2;
signed char c;
float z2;
char hb,slen;
hptr= str;
slen= 0;
first= 1;
if (zahl<0)
{
b= 1;
zahl= zahl*(-1);
}
if (nk>0)
{
for (hb= 0; hb< nk;hb++)
{
zahl= zahl*10;
}
}
z2= (zahl/1000);
gz1= z2;
gz2=gz1*1000;
zahl= zahl-gz2;
gz2= zahl;
if (gz1> 99999999)
{
strcpy(str,"error");
return;
}
if (b)
{
*str= '-';
str++;
slen++;
}
divisor= 10000000;
for (hb= 0;hb<6;hb++)
{
divisor=divisor/10;
c= gz1/divisor;
gz1= gz1-(c*divisor);
if (!((first) && (c==0)))
{
*str =c+48;
str++;
slen++;
first= 0;
}
}
c= gz1;
*str =c+48;
str++;
slen++;
divisor= 1000;
for (hb= 0;hb<2;hb++)
{
divisor=divisor/10;
c= gz2/divisor;
gz2= gz2-(c*divisor);
if (!((first) && (c==0)))
{
*str =c+48;
str++;
slen++;
first= 0;
}
}
c= gz2;
*str =c+48;
str++;
slen++;
*str= 0;
if (nk>0)
{
hptr= str;
hptr++;
for (hb= slen+1; hb>= slen+1-nk; hb--)
{
*hptr= *str;
str--;
hptr--;
}
str++;
*str= '.';
}
}
Schaust du SDCC Manual... If you're short on code memory you might want to use printf_small() instead of printf(). For the mcs51 there additionally are assembly versions printf_tiny() (subset of printf using less than 270 bytes) and printf_fast() and printf_fast_f() (floating-point aware version of printf_fast) which should fit the requirements of many embedded systems (printf_fast() can be customized by unsetting #defines to not support long variables and field widths). Be sure to use only one of these printf options within a project. http://sdcc.sourceforge.net/doc/sdccman.html/node97.html printf_fast_f()
Boooooooooooah ... hab ich natürlich gleich ausprobiert und ehrlich: printf_fast_f kannte ich nicht ! Hau ich mir an den Kopf, ärgere mich dass ich unnötig programmiert habe, freu mich aber, dass das beim nächsten mal deutlich einfacher geht ! Danke Ralph
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.