Hallo Leute!
Grundlage ist stdio.h von winavr
Code:
1
value=(temp<<12)/65535;// temp ist unsigned int
2
sprintf(s,"float: %2.4f \r\n",value);
Die Ausgabe ist folgende:
float: ?
Hat jemand eine Idee?
(s ist folgendermaßen deklariert: uchar s[30]; und ist damit groß genug
für mein Vorhaben
Danke für Hilfe!
Bei nem MSP430 ist es mir aufgefallen, dass die libc keine Floatzahlen
formatiern kann. Das wird hier auch so sein.
Ich denke, das wurde nicht implementiert, weil es zu viel Speicher bei
manchen Modellen verbraucht und es da zu Engpässen kommt.
Kann das jemand bestätigen bzw. dementieren?
Hallo Timo,
Dein Format passt nicht:
%2.4: die erste Zahl gibt die Gesamtstellen-Anzahl der Zahl an, incl.
des Dezimalpunktes und die zweite Zahl gibt die Anzahl der
Nachkommastellen an.
Du willst also eine Zahl mit 4 Nachkommastellen und Gesamtläng von nur 2
Stellen ausgeben.
Da kann der Compiler nicht.
Dreh die Zahlen um: %4.2 ergibt: zwei Nachkommastellen, einen
Dezimalpunkt und eine Vorkomma-Stelle, insgesamt also 4 Stellen.
Viele Grüße
Carlos
%6.4f wird nicht helfen! ich habe schon ganz neutral %f ausprobiert.
wenn temp zb. d376 ist dann kommt für value 23,5 raus. müsste doch mit
%2.2f darstellbar sein....
wie gesagt, selbst %f ohne große formatierungsflags erzeugt mir ein ?
Das Problem liegt hier daran, daß ein nicht-float-fähiges printf
verwendet wird.
Selbst wenn %1.3f als Formatstring verwendet wird, gibt printf etwas
sinnvolles aus.
Das hier vorliegende Problem aber liegt daran, daß die verwendete
Library eben aus Gründen der Codegröße gar keine Unterstützung für die
Float-Ausgabe via printf enthält.
Timo P. schrieb:
> Hallo Leute!>> Grundlage ist stdio.h von winavr>> Code:>
1
>value=(temp<<12)/65535;// temp ist unsigned int
2
>sprintf(s,"float: %2.4f \r\n",value);
3
>
In dieser Form wird nie etwas richtiges rauskommen.
Selbst wenn value ein Float ist, wird die Rechnung (temp << 12) / 65535
trotzdem auf Integern ausgeführt und erst danach in einen Float
umgewandelt. D.h. entweder passend in Float casten oder mit
Fixpunkt-Rechnen und selber umwandeln, wenn printf mit
Float-Unterstützung zu viel Speicher braucht.
> d376 ist dann kommt für value 23,5
0xd376 * 4096 / 65535 = 3383
> Dreh die Zahlen um: %4.2 ergibt: zwei Nachkommastellen, einen> Dezimalpunkt und eine Vorkomma-Stelle, insgesamt also 4 Stellen.
%[flags][width][.precision] [{h | l | ...}]type
width gibt an welche Mindestanzahl von Stellen ausgegeben wird, hat die
Zahl mehr Stellen werden diese immer ausgegeben (falls weniger wird je
nach Flags entsprechend aufgefüllt)
jetzt schon ;)
im übrigen geht 3.1 für z.B. 23.5 Grad ganz gut.
(ja hier ist es so warm....)
werd mal die türe vom serverraum aufmachen für kühle luft im büro...
Besten Dank an "sternst"
Timo P. schrieb:
> jetzt schon ;)>> im übrigen geht 3.1 für z.B. 23.5 Grad ganz gut.
Dann frage ich mich, wozu du die Gesamtgröße des Ausgebfeldes überhaupt
angibst, wenn du es sowieso zu klein angibst und nichts dabei findest.
23.5 besteht nunmal aus 4 Stellen ( '2' '3' '.' '5' )
was soll denn 0xd376 sein?
habe extra d geschrieben, um zu sagen, dass es sich um den dezimalwert
handelt
und du machst daraus einfach mal aus d... einen 0x... wert
Statt des zu kurzen %3.1f (das nur positive Werte mit einer
Vorkommastelle zulässt) genügt hier auch ein %.1f. Das bedeutet:
"Feldbreite so breit wie nötig, aber genau eine Nachkommastelle".
Wenn man tabellarisch mehrere Werte ausgeben möchte, ist es aber
sinnvoll, sich über die Feldbreite Gedanken zu machen.
Angenommen, wir haben folgende Werte: 1.34, 12.20, 263.48, 1234.56 und
-7827.21 und wollen diese immer mit zwei Nachkommastellen ausgeben.
Diese durch "%.2f" geschickt ergeben folgendes Bild:
"1.34"
"12.20"
"263.48"
"1234.56"
"-7827.21"
Das sieht als Tabelle richtig schlecht aus. Damit das vernünftig
aussieht, müssen die Werte rechtsbündig ausgegeben werden, so daß der
Dezimalpunkt immer an der selben Stelle steht.
Um das zu erreichen, muss eine unterschiedliche Anzahl von führenden
Leerzeichen ausgeben werden.
Nun könnte man die Stringlänge bestimmen und von Hand Leerzeichen davor
ausgeben, aber das ist gar nicht nötig - hier kommt die
Feldbreitenangabe von printf hilfreich ins Spiel. Ist nämlich die
angegebene Feldbreite größer als die tatsächlich benötigte, so stellt
printf führende Leerzeichen voran.
Bestimmen wir jetzt mal die benötigte Feldbreite.
Der "größte" Wert hat vier Vorkommastellen, also muss das Format darauf
angepasst werden. Hinzu kommen zwei Nachkommastellen, ein Dezimalpunkt
und das Vorzeichen, in Summe also 8 Zeichen.
Also lautet der Formatstring "%8.2f". Angewand auf obige Zahlen ergibt
sich dann folgendes Bild:
"¬¬¬¬1.34"
"¬¬¬12.20"
"¬¬263.48"
"¬1234.56"
"-7827.21"
(Leerzeichen sind der Klarheit halber durch ¬ ersetzt)
Bei der Ausgabe hexadezimaler Zahlen ist die Ausgabe führender Nullen
üblich, um klar erkennen zu lassen, welche Bitbreite die jeweilige Zahl
hat.
Um die Zahlen 0x12, 0xF, 0xD12 und 0xFEED als 16-Bit-Werte auszugeben,
ist eine Feldbreite von vier erforderlich (printf setzt kein 0x-Präfix,
das muss man selber machen).
"%4X" ergibt
"¬¬12"
"¬¬¬F"
"¬D12"
"FEED"
Um anstelle des führenden Leerzeichens Nullen auszugeben, muss
zusätzlich zur Feldbreite eine "0" vorangestellt werden:
"%04X" ergibt
"0012"
"000F"
"0D12"
"FEED"
Es ist also meistens sehr sinnvoll, sich mit den Formatspezifizierern
und Feldbreitenangaben von printf im Detail zu beschäftigen.
Rufus t. Firefly schrieb:
> Statt des zu kurzen %3.1f (das nur positive Werte mit einer> Vorkommastelle zulässt)
Kleine Korrektur: Das ergibt immer genau eine Nachkommastelle und n
Vorkommastellen (wenn es so viele gibt).
7.19.6.1 (Ansi C99)
> — An optional minimum field width. If the converted value has fewer> characters than the field width, it is padded with spaces (by default)> on the left (or right, if the left adjustment flag, described later, has> been given) to the field width. The field width takes the form of an> asterisk * (described later) or a nonnegative decimal integer.235)>> — An optional precision that gives the minimum number of digits to> appear for the d, i, o, u, x, and X conversions, the number of digits to> appear after the decimal-point character for a, A, e, E, f, and F> conversions, the maximum number of significant digits for the g and G> conversions, or the maximum number of bytes to be written for s> conversions. The precision takes the form of a period (.) followed> either by an asterisk * (described later) or by an optional decimal> integer; if only the period is specified, the precision is taken as> zero. If a precision appears with any other conversion specifier, the> behavior is undefined.
Missverständnis:
> > Statt des zu kurzen %3.1f (das nur positive Werte mit einer> > Vorkommastelle zulässt)>> Kleine Korrektur: Das ergibt immer genau eine Nachkommastelle und n> Vorkommastellen (wenn es so viele gibt).
Das war so gemeint, daß in die Feldbreite 3 eben nur positive Werte mit
einer Vorkommastelle hineinpassen - für alles andere wird die
Feldbreite entsprechend automatisch erweitert, was Du ja auch sehr
schön beschreibst.