mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Multiplikation mit Kommazahl


Autor: MaxMüller (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst Ergebnis=0 schreiben, wenn du mit 16bit Ganzzahlen rechnest.

Beschreib doch mal was du vorhast. Es gibt bestimmt eine einfachere 
Lösung die auch funktioniert.

Autor: Walter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
in welcher Zahlendarstellung soll denn das Ergebnis sein, wie wird es 
weiterverarbeitet?

Autor: RT (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ein word mal diese Konstante gibt nicht mehr sehr viel. Versuch doch mal 
ADC*71351753, behalte *0,000000000000001

RT

Autor: MaxMüller (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Brauchst du dabei wirklich 8 Stellen Auflösung ?
Der ADC liefert doch gerade mal 3 Stellen, da kannst du eigentlich 
spätestens  ab der 5. Stelle aufhören ohne dass sich am Ergebnis 
wirklich was ändert.

Autor: MaxMüller (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Axel R. (axelr) Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>0,000000071351753

das ist 15 Stellen, nur hiterm Komma. Kann man sicher irgentwie anders 
rum interpretieren (Float?)

/XlR.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Detlef _A (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Rehrmann (Firma: Rehrmann Elektronik) (j_r)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Falk (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Wolfram (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.