Forum: Mikrocontroller und Digitale Elektronik Fehler in der Float Funktion


von Martin S. (paul-stanley)


Lesenswert?

hallo zusammen,
ich hab probleme mit der float funktion.
es soll nur eine stelle nach dem komma angezeigt werden. allerdings auch 
im minus bereich.
das problem ist, dass das komma an einer unterschiedlichen stelle im 
minusbereich angezeigt wird und auch springt wenn die zahl 1 oder zwei 
stellen vor dem komma hat. so bekomme ich keine einheitliche anzeige 
hin.
weis jemand rat für mein problem ?

gruss martin



for (double f=-20.0; f<15.0; f=f+1.111) {
      char string[3];

      dtostrf(f,2,1, string);
      //if (!(f>=10)) {string[3]='\0';}
      if (!(f<=0)) {string[3]='\0';}

      //strpos(string,".");
      //itoa(u,string,10);
      LCD_Print(string, 6, 113, 2, 1, 1, yellow, black);
      delay_ms(450);


    }

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

"string" bietet Platz für drei Zeichen, was die abschließende \0 mit 
einschließt.

Das reicht für eine Floatingpoint-Zahl ganz und gar nicht; davon 
abgesehen ist ein Zugriff auf string[3] konsequenterweise illegal.

"string" muss mit Platz für mindestens 6 Zeichen deklariert werden:

-20.0 = '-', '2', '0', '.', '0', '\0'

von Martin S. (paul-stanley)


Lesenswert?

danke für den tipp.
hab die 3 auf 6 geändert.
das problem des "wandernden" komma bleibt aber gleich :-(

gruss martin

von Martin S. (paul-stanley)


Lesenswert?

scheinbar ist das problem, dass der wert immer linksbündig angezeigt 
wird und somit einige zahlen einfach stehen bleiben. komma sollte immer 
an der gleichen stelle positioniert werden. unabhängig von dem 
minuszeichen und ob eine oder zwei stellen vor dem komma stehen.
das geht glaub nicht so einfach.

von Stefan O. (stefano)


Lesenswert?

Hallo

Ist printf() eine Alternative für dich?
Damit kann man solche Dinge festlegen - schau dir einfach die 
entsprechenden "Flags?" an.

lg Stefan

von Martin S. (paul-stanley)


Lesenswert?

..soweit ich weis kann man da keine negativen werte übergeben

von Falk B. (falk)


Lesenswert?


von Stefan O. (stefano)


Lesenswert?

Es ist echt immer wieder faszinierend wie breit das Angebot an Artikeln 
hier ist.

lg Stefan

von Falk B. (falk)


Lesenswert?

@  Stefan Oberpeilsteiner (stefano)

>Es ist echt immer wieder faszinierend wie breit das Angebot an Artikeln
>hier ist.

Sind ja nur ~400 ;-)

MFG
Falk

von Martin S. (paul-stanley)


Lesenswert?

..ganz schön arrogant.
wenn es so einfach wäre, dass komma an einer festen position zu halten, 
frage ich mich, warum mir dann nicht jemand gütigerweise weiterhilft.
mit arroganten aussagen und links wo auf dieses problem auch nicht 
eingangen wird hilft mir nicht wirklich weiter.

von Gast (Gast)


Lesenswert?

So richtig habe ich Dein Problem nicht verstanden. Die einfachste 
Möglichkeit sollte aber ein sprintf bieten, wobei mit %6.1f formatiert 
werden könnte. Was dann auf der linken Seite zuviel an Leerzeichen steht 
kann man ausblenden.
Generell brauchen Ausgaben mit Nachkommastellen, die auch negativ werden 
können, immer ein wenig mehr Platz bei der Anzeige.

Blöd sieht es aus, wenn unsere transatlantischen Freunde kleine 
Millimeterwerte in inch angezeigt haben möchten. Da bekommt man immer 
lange Zahlen mit vielen Nullen. Vielleicht sind diese vielen Nullen der 
Grund für alles andere :-)

von Martin S. (paul-stanley)


Lesenswert?

die anzeige läuft momentan linksbündig. d.h.:
-10.5
-9.5
9.0
20.0

in der anzeige bleiben nicht mehr benutze zahlen stehen und auch die 
formatierung sieht so nicht wirklich toll aus.
-10.5
-9.55
9.055
20.05


aussehen sollte es wie folgt:
-10.5
 -9.5
  9.0
 20.0

von Martin S. (paul-stanley)


Lesenswert?

aktuell sieht der code wie folgt aus:

for (double f=-15.0; f<15.0; f=f+1.111) {
      char string[6];
      //sprintf(string,"e %.2f",f);        // ZielBuf02 =f(float), 
%3.2f=xxx.xxx (3vorkomma-,2nachkommastellen)
      dtostrf(f,2,1, string);
      //if (!(f>=10)) {string[6]='\0';}
      if (!(f<=0)) {string[3]='\0';}

      //strpos(string,".");
      //itoa(u,string,10);
      LCD_Print(string, 6, 113, 2, 1, 1, yellow, black);
      delay_ms(50);


    }

von Falk B. (falk)


Lesenswert?

@  Martin Schmid (paul-stanley)

Ein Blick in ein C-Grundlagenbuch enthüllt.

1
char string[6];
2
for (double f=-15.0; f<15.0; f=f+1.111) {
3
      sprintf(string,"e % #5.1f",f);
4
      LCD_Print(string, 6, 113, 2, 1, 1, yellow, black);
5
      delay_ms(50);
6
    }

>        // ZielBuf02 =f(float),%3.2f=xxx.xxx (3vorkomma-,2nachkommastellen)

Das ist ein Irrtum. 3.3 Sind NICHT 3 Vorkommastellen, sondern 3 Zeichen 
Gesamtbreite, davon zwei Nachkommastellen.

MfG
Falk

von Martin S. (paul-stanley)


Lesenswert?

..als ergebnis wird bei diesem code nur ein "e     ?" ausgegeben !!!

von Gast (Gast)


Lesenswert?

Dann fang doch mal ganz einfach an:

1. anstatt double nimm float
2. reserviere für string getrost 20 Byte, Geiz kann von großem Übel sein
3. verwende sprintf(s,"%5.1f",f);

Vielleicht sagst Du auch noch, welchen Prozessor Du einsetzt.

von Simon K. (simon) Benutzerseite


Lesenswert?

Wahrscheinlich beim AVR-GCC vergessen das float-printf mit einzulinken?

von Martin S. (paul-stanley)


Lesenswert?

hab einen atmel 2561 und AVR

code sieht nun so aus:

char string[20];
for (float f=-15.0; f<15.0; f=f+1.111) {
      sprintf(s,"%5.1f",f);
      LCD_Print(string, 6, 113, 2, 1, 1, yellow, black);
      delay_ms(350);
    }

folgende fehler kommen beim compilieren:
displaydemo.c: In function 'main':
displaydemo.c:334: error: 's' undeclared (first use in this function)
displaydemo.c:334: error: (Each undeclared identifier is reported only 
once
displaydemo.c:334: error: for each function it appears in.)
displaydemo.c:334: warning: format '%5.1f' expects type 'double', but 
argument 3 has type 'float'
make.exe: *** [obj/displaydemo.o] Error 1

von Karl (Gast)


Lesenswert?

Troll? Du schaffst es nicht einmal, richtig zu copy&pasten, beschimpfst 
andere aber als arrogant? Kopfschüttel
Kauf dir ein C-Buch und arbeite es durch. Das ist hier doch keine 
Spaßveranstaltung.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Karl wrote:
> Das ist hier doch keine Spaßveranstaltung.

Naja, meistens doch...irgendwie...

von Kanzler Gorkon (Gast)


Lesenswert?

@Martin Schmid

Es steht doch eh so toll in der Fehlermeldung, was verkehrt ist...

Ersetz mal "s" durch "string"

von Martin S. (paul-stanley)


Lesenswert?

das s hatte ich vorher schon durch string ersetzt.
aber dann kommt:

displaydemo.c: In function 'main':
displaydemo.c:334: warning: format '%5.1f' expects type 'double', but 
argument 3 has type 'float'

von Martin S. (paul-stanley)


Lesenswert?

..irgendwie dreht man sich hier nur im kreis.
der eine sagt "float"..der andere wieder "double"......oder mal 
"sprintf"..dann wieder "itoa"...langsam drängt sich mir der verdacht 
auf, dass die wo am meisten denken sie könnten das problem so einfach 
lösen, gar keine ahnung haben wie man es löst.

ein forum sollte eigentlich dafür da sein um hilfestellung zu geben und 
nicht so grosskotzig auf der tastatur rumzuklopfen.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

Martin Schmid wrote:
> ..irgendwie dreht man sich hier nur im kreis.
> der eine sagt "float"..der andere wieder "double"......oder mal
> "sprintf"..dann wieder "itoa"...langsam drängt sich mir der verdacht
> auf, dass die wo am meisten denken sie könnten das problem so einfach
> lösen, gar keine ahnung haben wie man es löst.
>
> ein forum sollte eigentlich dafür da sein um hilfestellung zu geben und
> nicht so grosskotzig auf der tastatur rumzuklopfen.

Jetzt mal ehrlich, das du keinen Schimmer von der Sache hast ist absolut 
klar.

Falks Beispiel war absolut ok, das du dich danach von Gast (Gast) in die 
Irre führen lässt irgendwie DEIN PROBLEM. Spätestens bei der 
Fehlermeldung des Compilers hätte ich zumindest mal mein HIRN 
eingeschaltet, solch absolut EINDEUTIGE Fehlermeldungen hab ich bei 
meinen Problemen selten.

Letzte Hilfe:

%[flags][width][.precision][length]specifier

sprintf(string,"%5.1f",f);
//Ist 5 Stellen Lang mit einer Nachkommastelle z.B. 123.4

Das Ganze passt in einen string[6], 5 Stellen und Stringende.

PS: Der Fehler liegt in deiner LCD_Print Funktion.

von Tim T. (tim_taylor) Benutzerseite


Lesenswert?

1
int main(void){
2
 char string[20];
3
 for (double f=-15.0; f<15.0; f=f+1.111) {
4
  sprintf(string,"e % #5.1f",f);
5
  printf(string); //Testausgabe
6
  printf("\n"); //Nur damit Ausgabe untereinander
7
 }
8
 getchar(); //Offenhalten des Fensters
9
 return 0;
10
}

Ausgabe:

e -15.0
e -13.9
e -12.8
e -11.7
e -10.6
e  -9.4
e  -8.3
e  -7.2
e  -6.1
e  -5.0
e  -3.9
e  -2.8
e  -1.7
e  -0.6
e   0.6
e   1.7
e   2.8
e   3.9
e   5.0
e   6.1
e   7.2
e   8.3
e   9.4
e  10.6
e  11.7
e  12.8
e  13.9
e  15.0

von Kanzler Gorkon (Gast)


Lesenswert?

@Martin Schmid

> ein forum sollte eigentlich dafür da sein um hilfestellung zu geben und
> nicht so grosskotzig auf der tastatur rumzuklopfen.

Und Du als Hilfesuchender bist nicht in der Position, diejenigen, die 
Dir Hilfe anbieten zu massregeln. Dass Du mit den Antworten, die 
großteils sinnvoll und gut sind, Dein Problem nicht (sebstständig) lösen 
kannst, liegt alleine in Deiner Verantwortlichkeit.
Warum interpretierst Du die Fehlermeldungen/Warnungen von Deinem 
Compiler nicht?
Willst Du nicht oder kannst Du nicht?

von Falk B. (falk)


Lesenswert?

@  Tim T. (tim_taylor)

>PS: Der Fehler liegt in deiner LCD_Print Funktion.

Nein, er hat auch nicht die Fliesskommaversion von printf gelinkt.
Das geht so.

- Im AVR Studio im Menu Project -> Configurations Options
- Custom Options
- im linken Fenster [Linker Options] markieren, WICHTIG!
- dann inten rechts in die Zeile eintragen
  -Wl,-u,vfprintf -lprintf_flt -lm
- ADD drücken, dann OK

Dann normal compilieren (F7). Dann gehts.

MfG
Falk

von Martin S. (paul-stanley)


Lesenswert?

hab seither nur das Programmers Notepad benutzt und lade gerade AVR 
studio und probiere es wie oben beschrieben nochmals.

von Martin S. (paul-stanley)


Angehängte Dateien:

Lesenswert?

..hab das avr studio installiert. allerdings wird da meine parallele 
datenverbindung nicht unterstützt. des weiteren gibt es den oben 
erwähnten menüpunkt auch nicht.
gibt es einen weg die änderung auch übers programmers notepad 
reinzubekommen ?

von Johannes M. (johnny-m)


Lesenswert?

Martin Schmid wrote:
> des weiteren gibt es den oben
> erwähnten menüpunkt auch nicht.
Den gibt es natürlich nur dann, wenn auch ein Projekt geöffnet ist!

von Falk B. (falk)


Lesenswert?

@ Martin Schmid (paul-stanley)

>..hab das avr studio installiert. allerdings wird da meine parallele
>datenverbindung nicht unterstützt. des weiteren gibt es den oben

War schon immer so. Nur Seriell oder USB.

MFG
Falk

von Martin S. (paul-stanley)


Lesenswert?

na ja..dann muss ich doch weiter mit dem programmers notepad 
weitermachen.
notfalls muss ich halt den string aufwendig von hand an die richtige 
stelle verschieben.

trotzdem danke für die hilfe.

von Falk B. (falk)


Lesenswert?

@ Martin Schmid (paul-stanley)

>na ja..dann muss ich doch weiter mit dem programmers notepad
>weitermachen.

???
Was ist an einer AVRStudio Installation so schwierig? Und deinen 
Programmer kannst du auch ohne AVRStudio nutzen, einfach nur ds HEX-File 
per AVR-Studio erzeugen und gut.

>notfalls muss ich halt den string aufwendig von hand an die richtige
>stelle verschieben.

?????????????????????????????????
Anstatt sich mal eine ordentliche Programmierumgebung zu schaffen lieber 
sinnlos rummurksen? Naja  . . . .

MFg
Falk

von Martin S. (paul-stanley)


Lesenswert?

?????
AVR Studio ist doch installiert.
gibt es da defizite beim lesen ????

von Falk B. (falk)


Lesenswert?

@  Martin Schmid (paul-stanley)

>AVR Studio ist doch installiert.

Und liegt dann das Problem? Projekt anlegen, Quelltext reinziehen, F7 
drücken. Kann man sogar nett simulieren.

MFg
Falk

von Martin S. (paul-stanley)


Lesenswert?

keine ahnung was da wieder los ist.
da schieb ich lieber den string bevor ich da noch stundenlang das avr 
studio überrede ein im programmers notepad auffähiges prg zu 
complilieren.


Build started 2.2.2008 at 19:02:53
avr-gcc.exe -mmcu=atmega2561 -Wl,-u,vfprintf -lprintf_flt -lm      -o 
testms.elf
c:/winavr-20071221/bin/../lib/gcc/avr/4.2.2/../../../../avr/lib/avr6/crt 
m2561.o:  In function `__vectors':
../../../../crt1/gcrt1.S:52: undefined reference to `main'
make: *** [testms.elf] Error 1
Build failed with 1 errors and 0 warnings...

von Falk B. (falk)


Lesenswert?

@ Martin Schmid (paul-stanley)

>keine ahnung was da wieder los ist.
>da schieb ich lieber den string bevor ich da noch stundenlang das avr
>studio überrede ein im programmers notepad auffähiges prg zu
>complilieren.

Der Compiler ist der gleiche, AVRGCC. Das einzige was AVRSTUDIO macht 
ist, dem Anfänger das Gefummel mit dem makefile abzunehmen. Das kann man 
aber auch wieder selber machen, einfach in den Optionen eintragen, 
external makefile.

MFG
Falk

von Martin S. (paul-stanley)


Angehängte Dateien:

Lesenswert?

..wenn man eine externe makefile datei auswählt kann man Linker Options 
nicht mehr setzen.

hab mal in meinen original makefile reingeschaut und da stehen unter 
Library Options genau die gleichen sachen drin die du mir auch schon 
geschrieben hast.

anbei der original (unter programmers notepad lauffähige) makefile.

von Falk B. (falk)


Lesenswert?

@ Martin Schmid (paul-stanley)

Und was sehen wir hier? Du nutzt NICHT die Floatig Point Pintf Version. 
Probiers mal damit
1
#---------------- Library Options ----------------
2
# If this is left blank, then it will use the Standard printf version.
3
#PRINTF_LIB = 
4
#PRINTF_LIB = $(PRINTF_LIB_MIN)
5
PRINTF_LIB = $(PRINTF_LIB_FLOAT)

Das leere PRINTF_LIB = auskommentieren und das letzte aktivieren, durch 
Entfernen des Kommentars.

MFG
Falk

von Martin S. (paul-stanley)


Lesenswert?

puh..das war eine geburt :-)

mit diesem code geht es jetzt wie gewünscht:


 char string[20];
 for (double f=-15.0; f<15.0; f=f+1.111) {
       sprintf(string,"%5.1f",f);
       LCD_Print(string, 1, 113, 2, 1, 1, yellow, black);
       delay_ms(350);
     }

wenn double durch float ersetzt wird, kommt ne warnung beim kompilieren. 
deshalb lass ich es jetzt so. darstellung ist wie gewünscht.


meine anfängliche vermutung, dass was in der funktion nicht richtig 
läuft, war  dann nicht ganz falsch.

vielen dank für eure hilfe.

gruss und einen schönen abend

martin

von Falk B. (falk)


Lesenswert?

@  Martin Schmid (paul-stanley)

>puh..das war eine geburt :-)

Herzlichen Glückwunsch. Was ist es denn? Junge, Mädchen oder AK?
(Insidergag für Mittermaier-Kenner)

> char string[20];
> for (double f=-15.0; f<15.0; f=f+1.111) {
>       sprintf(string,"%5.1f",f);
>       LCD_Print(string, 1, 113, 2, 1, 1, yellow, black);
>       delay_ms(350);
>     }

Schön, aber was bringt das dir? Wenn du sie nicht schon vorher verwendet 
hast, verballern dir sprintf und die Fliesskommazahlen ca 2,5kB Flash. 
Und das nur, um

e -15.0
e -13.9
e -12.8
e -11.7
e -10.6
e  -9.4
e  -8.3
e  -7.2
e  -6.1
e  -5.0
e  -3.9
e  -2.8
e  -1.7
e  -0.6
e   0.6
e   1.7
e   2.8
e   3.9
e   5.0
e   6.1
e   7.2
e   8.3
e   9.4
e  10.6
e  11.7
e  12.8
e  13.9
e  15.0

anzuzeigen?
Das geht, wie bereits geschrieben, mit Festkommaarithmetik 
wesentlich resourcenschonender. Dann reichen 50 Byte Flash.

MFG
Falk

von Martin S. (paul-stanley)


Lesenswert?

ne ne.
jetzt lassen wir es wie es ist, da alle 6 messwerte korrekt angezeigt 
werden.
das ganze prg incl. grafik verbraucht gerade mal 10 Kb und ich hab ja 
256 Kb flash auf dem board.

also lass ich es jetzt lieber lauffähig und geniese die eingesparte zeit 
um auf den fashcing zu gehen :-)

gruss und nochmals danke

martin

von Unbekannter (Gast)


Lesenswert?

> also lass ich es jetzt lieber lauffähig und geniese die eingesparte
> zeit um auf den fashcing zu gehen :-)

Da hast Du sogar recht.

Solange es keinen Grund zum Optimieren gibt, auf keinen Fall optimieren!

Frühes, zielloses Optimieren verschwendet Zeit und generiert Fehler.

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.