Hallo zusammen, ich möchte mit einem AVR eine Langzeit-Datenerfassung machen, dabei muss ich u.a. sekundenweise recht kleine Werte aufaddieren, die dann auf lange Sicht (> 1 Jahr) eine hoffentlich genau Summe ergeben sollen. Der Summenwert wird sich in der Größenordnung 10.000 - 100.000 (also 10^4 - 10^5), bewegen, die Sekundenwerte im Bereich 0.001 (also 10^-3) bei simplem Addieren in einer float (oder double, was auf dem AVR meines Wissens nach dasselbe ist) befürchte ich einen signifikanten Genauigkeitsverlust. Nun dachte ich, ich splitte die Werte in einen "großen" und einen "kleinen" Teil, addiert wird immer nur zum kleinen, und von Zeit zu Zeit inkrementiere ich den großen um den kleinen und setze den kleinen auf null zurück. Ich eine solche Vorgehensweise sinnvoll? Wenn nein, was dann? Wenn ja: wann übertrage ich vom kleinen in den großen? ich dachte an einen Schwellwert (wenn klein > schwelle dann übertrage klein nach groß) nur wo lege ich die Schwelle hin? In die Mitte der Wertebereiche? Danke, Michi
Ich hatte eben noch eine andere Idee: kurz zum Hintergrund: es soll eine Art "Wärmemengenzähler" werden, ich ermittle jede Sekunde (oder alle 10 Sekunden, das wird sich erst herausstellen) die momentane Wärmeleistung, zusammen mit der verstrichenen zeit sollte das die Wärmeenergie ergeben. Deswegen ist die Wärmemenge übers Jahr recht groß, die einzelnen Summanden aber recht klein. Nun zu meiner Idee: ich wandle das in "Impulse" um (ähnlich eines elektrischen Energiezählers), definiere z.B. 1 kWh = 1000 Impulse, addiere die kleinen Summanden auf, sobald diese Zwischensumme > 1 ist, erhöhe ich den globalen Impulszähler, und subtrahiere von meiner Zwischensumme den ganzzahligen Anteil (die nachkommastellen behalte ich) Summe = 3.14152 => Impulse +=3, Summe -= 3.0 (=> 0.14152) wäre das eine bessere Lösung?
Dann rechne deine Werte mal 1000 bei 3 bzw. 100000 bei 5 Nachkommastellen und pack sie in eine von diesen: http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Ganzzahlige_Datentypen_.28Integer.29 Wenn 32 bit zu wenig wird, nimm 64...
Für diesen Fall sind Gleitkommzahlen unpassend. Bei entsprechender Genauigkeit würde das nicht auffallen (außer durch evtl. unangenehme Rechenzeit), aber auf einem AVR hast du die Genauigkeit halt nicht. Unpassend deshalb, weil bei Zunahme des Betrags nach und nach die kleineren Stellen unterschlagen werden. Genau das kannst du nicht brauchen, wenn kleine Beträge aufaddiert werden sollen. Nimm dir Festkommzahlen passender Länge und Skalierung, und gut ist. Die Skalierung richtet sich danach, daß die kleinen Beträge angemessen abgebildet werden, die Länge danach, daß bei dieser Skalierung die Summe untergebracht werden kann. Wenn die so ermittelte Länge für den uC zu unhandlich ist, kann man auch mehrstufig rechnen. Angenommen, die Einzelwerte passen in maximal 15 Bit. Dann addiert man in einer Variable mit 16 Bit auf, und immer wenn das oberste Bit genutzt wird, löscht man es wieder und erhöht eine weitere Hilfsvariable um 1 (die anfänglich 0). Zum Schluß ergeben beide zusammen entsprechend verschoben die Summe.
Deine letzte Idee entspricht etwa meiner Aufteilung, nur dezimal statt binär. Beides geht, binär wäre effizienter.
Jep, sowas macht man nicht mit floats, einfache Integer-Arithmetik, wenn ein Integer voll Übertrag auf den nächsten...
Einen weiteren Genauigkeitszuwachs erhältst du, wenn du nicht sekündlich aufaddierst, sondern immer dann, wenn z.B. eine Energieeinheit (z.B. Wattsekunde) "voll" ist. D.h. du musst deinen Auswertalgorithmus so umbauen, dass er für jede Ws eine Festkommazahl erhöht. Gruß Roland
mich stört irgendwie der Titel des Beitrags... Ein AVR rechnet nicht ungenauer! Es ist vielmehr eine Geschichte welchen Datentypen und/oder Methoden man zur Berechnung benutzt, was die Genauigkeit bestimmt.
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.