Hallo Habe ein Frage zum float Datentyp. Benutze ein Grafikdisplay und möchte dort mehrere Fliesskommazahlen darstellen. Leider haben die Werte unterschiedliche Dezimalstellen und können nicht gleich eingerückt werden. Wie mann die Nachkommastellen ändert, weiss ich. Gibt es auch eine Möglichkeit, die "Vorkommastellen" anzugeben? U8glib.print(float(wert),3); Beispiel wie es ist: 1.635 243.757 Beispiel wie es sein sollte: 001.635 243.757 Danke für die Unterstützung
Genauer gesagt:
1 | char temp_str[20]; |
2 | snprintf(temp_str, sizeof(temp_str), "%06.3f", wert); |
3 | U8glib.print(temp_str); |
Jörg W. schrieb: > snprintf(temp_str, sizeof(temp_str), "%06.3f", wert); Aber Vorsicht. Bei der Feldbreite, den 6, ist der Dezialpunkt und ein mögliches Vorzeichen auch schon mit eingerechnet. Vor allen Dingen auf den Dezimalpunkt vergisst man gerne.
Karl H. schrieb: > Vor allen Dingen auf den Dezimalpunkt vergisst man gerne. Stimmt, 7.3 wäre besser. Das snprintf() hilft dabei dagegen, dass bei einer (auch nur versehentlich) sehr großen Zahl irgendwo der bereitgestellte Speicherplatz überläuft.
Jörg W. schrieb: > Das snprintf() hilft dabei dagegen, dass bei einer (auch nur > versehentlich) sehr großen Zahl irgendwo der bereitgestellte > Speicherplatz überläuft. Aber Vorsicht. Nicht alle Implementationen setzen in jedem Fall eine Terminierung (vgl Microsoft VC: _snprintf) auch, wenn sie es sollten. So kann man sich je nach System einen Folge-Fehler und eben wieder einen Puffer-Überlauf einhandeln.
Tim S. schrieb: > Microsoft VC: _snprintf Sie werden schon wissen, warum sie da einen Unterstrich davorsetzen … Aus dem Kontext (U8glib) würde ich mal schlussfolgern, dass das für einen AVR ist, und das snprintf() der avr-libc verhält sich in dieser Hinsicht so, wie es vom C99-Standard vorgeschrieben ist.
Leider wird Float snprintf bei der Arduino IDE nicht unterstützt. Gibt es noch eine andere Möglichkeit?
Mach es von Hand. Mit ein wenig Mathematik wie es sprintf machen würde. Du musst nur geschickt durch 10 teilen und mit cast nach int die Nachkommastellen Entfernen. Bspw. 23,5 / 10 = 2,35 cast int = 2 jetzt jagst du das durch switch case Und gibst ne '2' aus. Jetzt nimmst du die 2 wieder mal 10 und machst: 23,5 - 20 und Entfernst damit die höchste stelle. => 3,5 jetzt teilst du durch eine zehnerpotenz Weniger also 10^0 = 1 cast nach int switch case und hast '3'. Dann 3 * 10^0 abziehen Und durch die nächste potenz teilen. 0,5 / 10^-1 = 5. Usw usf.
Bruno N. schrieb: > Leider wird Float snprintf bei der Arduino IDE nicht unterstützt. > > Gibt es noch eine andere Möglichkeit? Ja. Guck in die Lernbetty hier im Forum und dort nach "conv.c". Da hast du sowohl Integer- als auch Float-Konvertierung in simplem C, sollte also problemlos verstehbar sein und auch auf nem AVR gehen. W.S.
Grundlage der printf Konvertierung ist oft eine Library-Funktion fcvt oder _fcvt, die ggf. auch direkt verwendet werden kann, wenn das der einzige Grund wäre, das vollständige printf reinzuziehen.
Er könnte auch dtostre() oder dtostrf() benutzen. Möglicherweise könnte man aber den Arduino-Kram auch davon überzeugen, die Gleitkommaversion der Bibliothek zu nutzen. A. K. schrieb: > Grundlage der printf Konvertierung ist oft eine Library-Funktion fcvt > oder _fcvt In der avr-libc ist es die Funktion __ftoa_engine().
Elec-lisper schrieb: > switch case Was "switch und case" hier sollen, weiß ich nicht, ich habe das mal so gemacht:
1 | void printFloat(char* buff, float value) { |
2 | int intval = (int) floor(value); |
3 | int decval = (int) floor((value - (float) intval) * 1000.0); |
4 | sprintf(buff, "%d.%03d", intval, decval); |
5 | }
|
snprintf() wäre natürlich besser, und statt "%d.%03d" wäre bei dir wohl "%03d.%03d" angebracht. Ich weiß, da sind überflüssiger Code und Casts drin, das überlasse ich dem Optimierer, es zu entfernen. Ich will halt meinen eigenen Kram auch nach 2 Jahren noch von der Intention her verstehen :-)
Kay R. schrieb: > Was "switch und case" hier sollen, weiß ich nicht, Das war für den Fall, dass keim sprintf oder floor zur Verfügung steht. Kay R. schrieb: > Ich will halt meinen eigenen Kram auch nach 2 Jahren noch von der > Intention her verstehen :-) Das erledigt ja die korrekte Benennung und die Kommentare im Code für dich.
Du kannst doch einfach anstelle von switch case ASCII 0 + x rechnen und bekommst auch die richtige Zahl raus. Spart code size, ist schneller, da nur eine instruktion und einfach zu verstehen. Wobei die paar Instruktionen, die man spart sind gegen float Berechnungen auch egal.
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.