Forum: Mikrocontroller und Digitale Elektronik AVR float Genauigkeitsproblem


von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

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

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

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?

von hp-freund (Gast)


Lesenswert?

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...

von Klaus W. (mfgkw)


Lesenswert?

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.

von Klaus W. (mfgkw)


Lesenswert?

Deine letzte Idee entspricht etwa meiner Aufteilung, nur dezimal statt 
binär. Beides geht, binär wäre effizienter.

von Steel (Gast)


Lesenswert?

Jep,

sowas macht man nicht mit floats, einfache Integer-Arithmetik, wenn ein 
Integer voll Übertrag auf den nächsten...

von Roland P. (pram)


Lesenswert?

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

von nur mal so (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.