Forum: Mikrocontroller und Digitale Elektronik Gleitkommaausgabe mit SDCC


von Ralph S. (jjflash)


Lesenswert?

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= '.';
  }
}

von Bernd N. (Gast)


Lesenswert?

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()

von Ralph S. (jjflash)


Lesenswert?

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
Noch kein Account? Hier anmelden.