Hallo, aufgrund gewisser Algorithmen sehe ich mich im Moment gezwungen mich mit dem Thema "Berechnungen mit Kommastellen auf einem AVR Mikrocontroller" zu beschäftigen. Die Grundvoraussetzungen: a= 0...255 b= 0...255 c = 0...255 d = 0...255 Die Formeln: x = ( 4 + ( (a-b) / (c-d) ) *60 y = (c - d) / c Das Ergebniss der ersten Formel hat einen Wertebereich von 0...360 ( die 4 könnte auch eine 0 oder 2 sein). Die zweite Formel ergibt einen Wertebereich von 0...1 Mein Problem ist nun das folgende: Da ich in assembler programmiere, bin ich es schlicht und einfach nicht gewohnt mit Kommazahlen zu programmieren. Genauer gesagt, mir fehlt defakto ein Gedankenansatz dafür. Aufgrund der Tatsache das ich die Ergebnisse später weiter verwenden möchte schwebt mit eine Genauigkeit von 4 oder 5 Nachkommastellen vor. Meine Frage dazu: Wie könnte man soetwas realisieren ?! (kein Code sondern Gedankenansätze) Grüße, Ralf B.
fixkomma 8 + 8 bit dividieren und multiplizieren kann man mit add und shift in einer schleife. schreib dir mal ein paar einfache beispiele in binär auf unsd dann dividiere wie in der grundschule
Wenn Du die 360 mit 5 Nachkommastellen brauchst, also 8 gültige Stellen, brauchst Du 26 Bits (36000000 = 0x2255100). Wenn Du sagst, 4-5 Nachkommastellen, genügen evtl. 24 Bits (3 Bytes). Für 0..1 mit 4-5 Stellen sind 16 bits (2 Bytes) ausreichend. Multiplizieren geht mit ein paar MUL- und ADD-Befehlen, Dividieren mit einer Schleife. Was passiert mit den Ergebnissen? Davon hängt es auch noch ab, wie die Zahlen optimal dargestellt werden. Beim Fixkomma-Rechnen skaliert (multipliziert) man alle Größen (meist mit einem Vielfachen von 2). Lies mal den Thread "Rechnen mit dem AVR", da habe ich ein wenig dazu geschrieben.
@Ralf: Die Klammerung eines Ausdruckes stimmt nicht. 4 offene Klammern, 3 geschlossene. Da gibt es mehrere Möglichkeiten, ich kann nicht raten, wie es richtig sein sollte. Darum mache ich mal ein eigenes Beispiel (das ist schon gut 10 Jahre her mit dem 8051, ist aber beim AVR sicher gleiches Prinzip, mal sehen, ob ich das vom Prinzip noch hinkriege): Angenommen, man will x = a * b / c. Kommastellen treten nur durch die Division auf. Sei a = 10d; b = 10d; c = 3d. (Postfix d = dezimal) Das Ergebnis soll 33,3333d sein. Jetzt rechne ich zuerst den Zähler des Bruches: x = a * b in einer Binärmultiplikation. In x steht das Teilergebnis 100d oder in Binärform 64h. Pro erwünschter Nachkommastelle muß man das Ergebnis vor der Division mit dem Faktor 10d erweitern, also für 4 Nachkommastellen mit 10000d multiplizieren: x = x * 10000d. Gebe ich im Assembler 10000d o.ä. Syntax (dezimal) an, wandelt der die Konstante automatisch nach binär bzw. hexadezimal (2710h). In 4 Einzelschritten nacheinander mit 10d (0ah) multiplizieren ist genauso möglich, je nachdem was die Rechenroutine zuläßt. Jetzt steht in x das Teilergebnis 1000000d, aber in Binärform als 0F4240h. Erst danach dividiert man: x = x / c. Erfordert eine Divisionsroutine 32bit/16bit oder 32bit/32bit o.ä.. Ergibt 333333d, steht noch in Binärform (051615h) im Speicher x. Dann wandelt man das Ergebnis von Hexadezimal (binär) nach Dezimal. Dafür brauchst du eine Wandlungsroutine bin-bcd, am besten mit einstellbarer Bitbreite. Entweder du schreibst sie selbst oder suchst im Netz danach. Beim Ergebnis, sind die 4 Stellen rechts jetzt Nachkommastellen. D.h., gibt man sie z.B. am Display aus, muß man den Dezimalpunkt von der niedrigstwertigen Stelle 4 Stellen nach links schieben. Ich hoffe, das hilft zumindest mal fürs Verständnis. Mit den Bitbreiten mußt du dich dann noch etwas herumärgern:-) Gruß Dietmar
Nuja, die Klammer die fehlte kommt vor die + 60 ... is mir gar net aufgefallen, das ich die übersehen habe .... Hmm, das liest sich soweit ganz simpel und schlüssig ... trotzdem bleiben mir jede Menge Fragen offen ... z.B. wo definiere ich das Komma ?! a) im Binären oder b) im Dezimalem Bereich ?! nuja .. ich glaube, das werde ich mal in aller Ruhe auskaspern ... bei nem Bier oder so. Grüße, Ralf B.
@Ralf: Ich hoffe, das Bier hat geschmeckt....... Das Komma ist völlig Wurscht: Das ist bei Binärzahl und Dezimalzahl gleich. Gruß:-) Dietmar
Hallo, Nuja, das Prinzip hab ich glaube erst mal verstanden ... Ich muss mir meine Formeln nur so umbauen, das ich die Anzahl der gewünschen Nachkommastellen im Ganzzahlenbereich hab (mit nem Faktor). Eine Frage hab ich nun allerdings noch, ist der Faktor absolut egal ? Also kann ich anstatt z.B. 100d auch 100h nehmen ? Grüße, Ralf B.
"Also kann ich anstatt z.B. 100d auch 100h nehmen ?" Ja, habe ich doch oben schon geschrieben: Was passiert mit den Ergebnissen? Davon hängt es auch noch ab, wie die Zahlen optimal dargestellt werden. Beim Fixkomma-Rechnen skaliert (multipliziert) man alle Größen (meist mit einem Vielfachen von 2). Kommt darauf an, in welchem Wertebereich die Eingangsvariablen liegen und was Du danach mit dem Ergebnis machen willst. Anzeigen, weiterrechnen, abspeichern, vergleichen??
Die Ergebnisse werden in gewissen anderen Berechnungen weiterverwendet und im Endeffekt auch ausgegeben. Nuja .. ich setz mich jetzt erst mal hin und bau die Formeln um ... besser ist das. Grüße. Ralf B.
@Ralf: Wie im Beispiel oben beschrieben, so ähnlich habe ich z.B. das Ergebnis einer AD-Wandlung 10 bit einer Spannungsmessung auf einem LCD-Display ausgegeben. Für eine weitere Verwendung des Ergebnisses, spielen wiederum die Anforderungen an die weitere Anwendung, z.B. Genauigkeit, eine Rolle. Und die Überlegungen mit Bitbreiten und Skalierungen beginnen von neuem. Berechnungen in Assembler sind gegenüber C jedoch eine reine Sysiphusarbeit. Für ein industrielles Projekt lohnt sich daher auf Dauer auch der hohe Anschaffungspreis eines C-Compilers, da man dann mit den Umsetzungen und Umwandlungen nichts mehr am Hut hat. Den Preis holt man durch Zeitersparnis wieder rein. Vielleicht kannst du auch mal einen Gedanken daran verschwenden, Fließkomma in Assembler zu programmieren. Das ist zwar ein schöner Aufwand, aber dann hat man wenigstens mit den Bitbreiten nichts mehr am Hut, da die dort fest sind (z.B. 24 bit Mantisse, 8 bit Exponent). Und der Wertebereich ist enorm. Vielleicht findet sich sogar was fertiges im Netz. Wenn ich mich recht erinnere, gibt es z.B. von Microchip, kostenlos downloadbar, Fließkomma-Routinen in Assembler für den PIC. Langsam muß Fließkomma auch nicht sein: Bei meinen gegenwärtig verwendeten Philips LPC2000 (ARM7, 32 bit) rechnet Fließkomma schneller als die Rechnung mit Integer-Werten. Das kannte ich bisher nicht, und es ist wirklich enorm! Gruß Dietmar
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.