Martin Fischer schrieb:> Wie kann ich diese Zwei in eine machen die dann so aussieht:> z1,z2, also dass z1 vorkommastellen sind und z2 Nachkommastellen?
Wie sieht das Format dieser "Nachkommastellen" denn aus?
Wenn z.B. die "Nachkommastellen" im Bereich von 0..9999 wären, dann
würde das so gehen:
1
floatf=z1+float(z2)/10000.0;
> Wie kann ich diese Zwei in eine machen die dann so aussieht:
Was ich gerne wissen würde: wofür brauchst du diese Zahl?
Danke, berecnet habe ich geschafft, aber auf einem anderen Weg, ich
demonstriere kurz was ich brauche:
Temperaturmessung:
uint8_t digit = 32;
uint16_t decimal = 4493;
-> Temperatur ist 32.4493 °C
Ich mag das jetzt in eine Zahl packen:
uint32_t temp = (digit *10000 + decimal)/10000
Und das dann auf dem Display ausgeben -> erst zu nem char array machen:
char buffer[20];
sprintf(buffer, "%d C", temp);
-> Fehler: temp != decimal...
Wie mache ich das?
Und ist uint32_t überhaupt richtig um die zu "addieren"?
Martin Fischer schrieb:> Ich mag das jetzt in eine Zahl packen:> uint32_t temp = (digit *10000 + decimal)/10000
Wozu dann durch zehntausend teilen? Ein Integer kann keine
Nachkommastellen speichern. Warum speicherst du nicht einfach milliGrad
in einem Integer?
> Ich mag das jetzt in eine Zahl packen:> Und das dann auf dem Display ausgeben -
Warum erst zusammenpacken und dann wieder auseinanderdröseln? Gib doch
erst die Vorkommastellen aus, dann ein Komma, dann die Nachkommastellen.
Das ist das Einfachste...
> Temperaturmessung:> uint8_t digit = 32;> uint16_t decimal = 4493;> -> Temperatur ist 32.4493 °C
Ähm, wenn GENAU das deine Anwendung ist, dann bezweifle ich sehr, dass
du überhaupt so genau Messen kannst...
Martin Fischer schrieb:> Auf dem Display steht aber nur "0.0000 C", warum?
Weil in grad und grad_dec jeweils Null ist?
> therm_read_temperature(grad, grad_dec);
Diese Funktion KANN die Werte von grad und grad_dec nicht ändern. Du
solltest dir dringend anschauen, wie Funktionen mehrere Werte bearbeiten
können. Mein Tipp: man verwendet dafür dann Pointer...
Probiers also einfach mal so:
> Warum erst zusammenpacken und dann wieder auseinanderdröseln? Gib doch> erst die Vorkommastellen aus, dann ein Komma, dann die Nachkommastellen.> Das ist das Einfachste...
Aber ich brauche die Zahl dann noch zum weiteren Rechnen, also wie kann
ich meine Temperatur zusätzlich noch in eine zahl packen um damit zu
rechnen?
Martin Fischer schrieb:> Aber ich brauche die Zahl dann noch zum weiteren Rechnen, also wie kann> ich meine Temperatur zusätzlich noch in eine zahl packen um damit zu> rechnen?
Wenn du unbedingt mit Integern weiterrechnen willst, dann rechne in
milliGrad (aka. Festpunktartihmetik). Am einfachsten ist aber, du
verwendest float...
Martin Fischer schrieb:> uint32_t temp = (digit *10000 + decimal)/10000
digit * 10000 <=> 32 * 10000 = 320000
+ decimal <=> + 4493 = 324493
/ 10000 <=> / 10000 = 32
Dein Problem ist das du nur mit Ganzzahlen(Integer) arbeitest, wenn du
aber 324493 / 10000 erhältst du allerdings eine Zahl mit
Nachkommastellen(Fließkommazahl). Weil temp und ALLE anderen Variablen
vom Typ Integer sind werden die Nachkommastellen abgeschnitten.
Bei entsprechender Compiler-Optimierung wird die komplette Rechnung
wahrscheinlich sogar entfernt werden.
Die Frage ist nun ob du mit der kompletten Zahl noch rechnen möchtest
oder ob du sie nur zur Darstellung/Ausgabe benötigst.
Musst du noch damit rechnen, kannst du
a) Festkommaarithmetik verwenden, dann müssen alle weiteren Operanden
noch mit 10000 multipliziert werden. Erst am Ende wenn es zur
Darstellung kommt wandelst du die Zahl in eine Fließkommazahl.
b) Du rechnest komplett mit Fließkommazahlen so wie Lothar es dir weiter
oben gezeigt hat.
Wenn du die Zahl nur noch darstellen möchtest und sie unbedingt in einer
Variablen speichern möchtest kann die Zahl auch anders zusammen gepackt
werden.
uint32 temp = (digit << 16) + decimal;
char buffer[20];
sprintf(buffer, "%d.%d C", temp >> 16, temp & 0xFF);
Martin Fischer schrieb:>> float>> Ich brauche aber die 4 Nachkommastellen..
Was für ein Monster-Thermometer hast du denn da, daß du dafür eine
Auflösung von 1/10000 Kelvin brauchst, und wieviele Millionen kostet
sowas?
Wenn du Temperaturen auf 6 signifikante Stellen messen kannst, dann hast
du auch noch Geld übrig, eine C-Programmierer zu bezahlen, der dir deine
SopW-Probleme löst. (warum glaubt man heute eigentlich blind an jede
Zahl, die per 7-Segment angezeigt wird?)
Martin Fischer schrieb:> Es ist ein DS18B20 auf 12bit Auflösung...
LOL
Aus dem Datenblatt:
It has an operating temperature
range of -55°C to +125°C and is accurate to
±0.5°C over the range of -10°C to +85°C. In
Also reicht eine Nachkommastelle.
Error:
prop -fno-inline-small-functions -I. -mmcu=atmega328p -DF_CPU=8000000
main.c: In function ‘main’:
main.c:27:23: error: expected expression before ‘double’
make: *** [main.o] Fehler 1
Was bedeutet das denn jetzt?
Ich habe alle floats einfach mit double ersetzt
>Ich habe alle floats einfach mit double ersetzt
Ich vermute eher, das Du alle Strings "float" im Programmtext durch den
String "double" ersetzt hast.
>main.c:27:23: error: expected expression before ‘double’
Gut, das wir die Zeile 27 nicht sehen können. Da wird das raten viel
spannender.
Martin Fischer schrieb:> Zeile 27:> temp = grad + double(grad_dec)/10000.0;
Da gehört ein Cast hin. Den schreibt man in ().
Aber der ist auch gar nicht nötig, da 10000.0 schon ein double ist und
somit die Division schon in double berechnet wird.
Martin Fischer schrieb:> double(grad_dec)
Das ist nicht C. Sowas geht in C++, aber nicht in C. In C sieht ein
Cast so aus:
1
(double)grad_dec
Martin Fischer schrieb:> main.c:28:9: warning: format ‘%f’ expects argument of type ‘double’, but> argument 3 has type ‘float’ [-Wformat]
Das ist merkwürdig. Normwalerweise wird das implizit nach double
konvertiert, ohne Warnung.
Dein Problem ist, daß du die Doku der avr-libc nicht gelesen hast. Da
floating-point sehr viel Flash braucht, unterstützt das per default
gelinkte printf keine Gleitkommazahlen.
Bitte durchdenke alles nochmal genau:
Brauchst du wirklich Dezimalzahlen? Dein Thermometer hat eine
Genauigkeit von 0.5°C. D.h., wie schon gesagt wurde, du brauchst nur
eine Dezimalstelle. Alle weiteren haben keine Aussagekraft!
Nun könntest du auch alles mit Integer rechnen, indem du das Ergebnis
mit 10 multiplizierst um die eine benötigte Dezimalstelle weg zu
bekommen. Das ist schneller und verbraucht weniger Speicher.
Zur Ausgabe auf dem Display kannst du dann entweder die Zahl mit
Division durch 10 in ein Double speichern und wie gehabt ein Double mit
sprintf am LCD ausgeben. Das dauert aber sehr lange, da die Umwandlung
eines Double in einen String sehr Rechenintensiv ist.
Wieder besser ist, du machst das 'manuell'. D.h. du teilst die Zahl
durch 10, speicherst das Ergebnis in ein Int. Die Zahl mit 10
multipliziert und von der Ausgangszahl subtrahiert gibt dir die
Dezimalstelle. Beides sind Int, beide können per sprintf mit minimalen
Rechenaufwand ausgegeben werden.
(Falls ich bei obiger Rechnung einen Denkfehler habe, so korrigiert mich
bitte)
Bitflüsterer schrieb:> temp = grad + double(grad_dec)/10000.0;> Da hat sich Lothar verhauen. Zuviel VHDL nehme ich a. :-)
Ach verd*%&/$§
Ich könnte aber auch behaupten, ich hätte das gemacht, dass Martin mal
ein wenig mitdenkt und keiner könnte das Gegenteil beweisen... ;-)
Frank M. schrieb:> Nun könntest du auch alles mit Integer rechnen, indem du das Ergebnis> mit 10 multiplizierst
Ja, dann eben in ZehntelGrad statt in milliGrad...
Martin Fischer schrieb:> Ich brauche aber die 4 Nachkommastellen...
Bitte die nächste Scheibe der Salami: Wofür brauchst du die real nicht
vorhandenen 4 Nachkommastellen.
Nochmal zum Mitschreiben: wenn dein Sensor eh' nur eine halbe
signifikante Nachkommastelle ausgibt, dann ist es absolut sinnlos, wenn
du dir eine 5000 fach höhere Auflösung herrechnest. Die Genauigkeit
bleibt trotzdem gleich schlecht.
Ja gut, da hast du recht :D
Aber ich bin ANfänger und weiß sowas noch nicht :P
naja, ich "Spiele" einfach jetzt mit allen werten *10, ist leichter,
schneller, besser :D
Danke trotzdem an euch allen!
Nichts für ungut aber:
Martin Fischer schrieb:> Aber ich bin ANfänger und weiß sowas noch nicht :P
Casten und Fehlermeldung lesen gehört sowas von zu den Grundlagen,
deshalb lerne sie und komme mit ihnen zurecht oder hör auf. Du kannst
nicht immer wegen jedem kleinen Scheiß das Forum zumüllen.
Ganz so schlimm würde ich das nicht sehen. Nur, oft wenn (von Anfänger
und Anderstgläubigen) auf C geschimpft wird, hat der Compiler alles
wichtige angemerkt, nur hatte man vorgezogen es zu ignorieren. Also
bitte lesen. Wenn's dann allzu verwirrend wirkt, hilf sicher jemand ;-)
Frank M. schrieb:> ...> Wieder besser ist, du machst das 'manuell'. D.h. du teilst die Zahl> durch 10, speicherst das Ergebnis in ein Int. Die Zahl mit 10> multipliziert und von der Ausgangszahl subtrahiert gibt dir die> Dezimalstelle. Beides sind Int, beide können per sprintf mit minimalen> Rechenaufwand ausgegeben werden.>
So:
@ Lothar Miller
>Ich könnte aber auch behaupten, ich hätte das gemacht, dass Martin mal>ein wenig mitdenkt und keiner könnte das Gegenteil beweisen... ;-)
Dazu nehme ich 'ne Knoblauchzehe. Wirst schon sehen. :-)
@ Martin
Was soll Dein letztes Posting sein? Eine Frage oder eine Feststellung?
Nebenbei: Ist das nun C oder C++? Leg Dich mal fest. :-)