Multiplikation mit Kommazahl

Gast #489249
Lesenswert?
• ▲
▼
Im Rahmen der Weiterverarbeitung einer vom ADC eines Atmega8 gewandelten 
Spannung muss ich den eingelesenen Wert mit einer recht kleinen 
Kommazahl multiplizieren. Also in der Art:

Ergebnis = ADC-Wert * 0,000000071351753

In Bascom ist das ja kein Problem. Nur muss ich das leider in Assembler 
lösen. Allerdings fehlt mir da im Moment ein gescheiter Lösungsansatz. 
Kann mir da jemand evtl. weiterhelfen?
Gast #489275
Lesenswert?
• ▲
▼
Es geht hierbei um die Aufloesung eines Polynoms 6. Grades, welches die 
nichtlineare Kennlinie eines Sensors beschreibt.

Also ich muss da nicht nur einmal ADC*0.0000000xxxxx rechnen sondern im 
Prinzip so:

Ergebnis = ADC*0.0000000xxxxxxxx
Ergebnis = Ergebnis - 0.000000xxxxxxxx
Ergebnis = Ergebnis * ADC
Ergebnis = Ergebnis + 0.00000000xxxxxxxx
Ergebnis = Ergebnis * ADC
Ergebnis = Ergebnis - 0.00000xxxxxxxx
Ergebnis = Ergebnis * ADC
Ergebnis = Ergebnis + 0.000xxxxxxxx
Ergebnis = Ergebnis * ADC
Ergebnis = Ergebnis - 0.0xxxxxxxx
Ergebnis = Ergebnis * ADC
Ergebnis = Ergebnis + 0.0xxxxxxxx
Gast #489284
Lesenswert?
• ▲
▼
Das kann man evtl. schon machen, da muss ich noch mal schauen. Mir geht 
es aber halt darum, wie ich die Multiplikationen möglichst effizient 
hinbekomme. Und da fehlt mit irgendwie immer noch der richtige Ansatz.
#489338
Lesenswert?
• ▲
▼
Mach doch erstmal ne Genauigkeitsabschätzung, wieviel Iterationen 
überhaupt nen Sinn ergeben.

Aus 0..1023 kannst Du doch nie 8 Digits rauskitzeln !

Maximal 3 Digits, eher noch weniger je nach Nichtlinearität, dann ist 
Ende der Fahnenstange.

Wenn ich das in Assembler machen müßte, würde ich mit Excel ne Tabelle 
von etwa 50 Stützwerten ausrechnen lassen und dazwischen einfach linear 
interpolieren.


Peter
Gast #489414
Lesenswert?
• ▲
▼
Max, Deine kleinste Zahl ist ~10e-8, die größte ~10-2, macht 6 
Zehnerpotenzen Dynamik, das entspricht 20Bit, 10Bit AD Wandler macht 
nochmal 10Bit, zusammen 30, da muß Du in Integer schon mit 64Bit 
rechnen, 32 reichen da nicht mehr. Oder Du muß in Assembler und float 
rechnen. Beides nicht so schön.

Ich schließe mich meinen Vorrednern an: Die Genauigkeit, die Du 
anstrebst, brauchst Du sicher nicht. 20Bit Rechendynamik bei 10Bit AD 
Wandler  Eingangsdynamik ist bullshit, das geht immer anders. Die 
Genauigkeitsanforderungen solltest Du nochmal überdenken.

Cheers
Detlef
(Firma: Rehrmann Elektronik) #489450
Lesenswert?
• ▲
▼
@Max:
Ein Polynom 6. Grades sieht normalerweise so aus:
Ergebnis = a0 + a1*ADC + a2*ADC^2 + a3*ADC^3 + ... + a6*ADC^6
Im Prinzip geht das immer mit einfacher Festkommaarithmetik. Das ist in 
Assembler nicht so schwierig. Die sehr kleinen Werte, z.B. a6, werden 
vermutlich mit den Polynomtermen höheren Grades multipliziert, sodass 
das die einzelnen Terme am Ende immer einen "normalen" Wert ergeben. 
I.d.R. reicht dann eine 32-Bit-Festkommaarithmetik, z.B. mit 16 
Vorkomma- und 16 Nachkommastellen oder auch 24 Vorkomma- und 8 
Nachkommastellen. Wenn Du jetzt z.B. den Term a6*ADC^6 wie folgt 
aufspaltest
a6*ADC^6 = a6^(1/6)*ADC * a6^(1/6)*ADC * ... * a6^(1/6)
bleibst Du idealerweise immer in Deinem 32-Bit-Zahlenbereich. Du mußt 
Dir halt vorher überlegen, in welchem Wertebereich der ADC liegt, damit 
eine 32-Bit x 32-Bit-Multiplikation ein vernünftiges Ergebnis liefert. 
Du mußt ja nach der Multiplikation, die 64 Bits liefert, immer 32 Bits 
abschneiden können, ohne das Ergebnis nennenswert zu verfälschen. 
Sinnvollerweise verschiebt man die Binärzahlen vor der Multiplikation 
soweit nach links, dass die MSBs möglichst aufgefüllt werden und teilt 
das Produkt entsprechend wieder durch Rechtsschiebung. Dadurch erreicht 
man maximale Rechengenauigkeit. Bei komplizierten Formeln würde ich dann 
aber lieber eine Fließkommaarithmetik verwenden.

Jörg
Gast #489482
Lesenswert?
• ▲
▼
@Peter Dannegger

>Mach doch erstmal ne Genauigkeitsabschätzung, wieviel Iterationen
>überhaupt nen Sinn ergeben.
>Aus 0..1023 kannst Du doch nie 8 Digits rauskitzeln !

Klar, sogar 10! Allerdings nur binäre ;-)

MFG
Falk
Gast #489504
Lesenswert?
• ▲
▼
>Bei komplizierten Formeln würde ich dann aber lieber eine >Fließkommaarithmetik 
verwenden
Du hast ihm gerade nachgewiesen, das er auch bei 32Bit Festkomma 
arithmetik aufpassen muss, das er nichts verliert. Ein float (und auch 
double) auf dem AVR hat 32Bit, 8 Bit Exponent, Mantisse: 23 Bit
Mit deiner Mantisse von 23Bit wird die Situation wohl nur noch 
verschlechtert.
Obwohl bei:
>Ergebnis = ADC-Wert * 0,000000071351753
also wenn BASCOM nicht mit 64bit double rechnet wird es wohl kaum 
schlechter.
Stichwort: Maschinengenauigkeit

Mach es wie Peter vorschlägt mit einer Tabelle und Interpolation, selbst 
mit nur 50 Stützwerten würde ich davon ausgehen das das schon genauer 
ist, als dein jetziges BASCOM Programm. Warum muss das eigentlich 
unbedingt in Assembler sein?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren