Hallo noch mal... Jetzt sieht das Problem so aus. Es gibt ne riesige Zahl 32bit lang, die muss ich mit einem koeffizient von 50/(2^32), also ungefaehr 0,011 mal nehmen und das Ergebniss dann runden. Da im endeffekt eine kleinere Zahl rauskommt, will ich die in 24 bits speichern. Wie wird solche Multiplikation gemacht? Wie geht man voran. <DANKE>
Das ist abhängig vom verwendeten Prozessor / Controller. Ich vermute, es geht um Assembler?
Erstens könnte man einen Compiler befragen. ;-) Zweitens ist natürlich eine 32-bit-Zahl geteilt durch 2^32 weiter nichts als eine andere Betrachtung ebendieser 32-Bit Zahl. Im Wesentlichen ist das also eine Multiplikation mit 50. Die größeren Probleme sind mögliche Wertebereichsüberläufe. Wenn der Wertebereich der Eingabezahl so klein ist, daß sie auch nach einer Multiplikation mit 50 die 32 Bits noch nicht überschreitet, ist das nicht weiter schwierig, ansonsten wird's aufwendig(er).
@thkais Entschuldigung, habe vergessen zu sagen, dass es um einen AT90s2313 geht und natuerlich um Assembler, mit Bascom oder c ist das gar kein Problem, leider wird sehr viel Speicher verbraucht. @Joerg Wunsch Ja, das ist mir klar, dass einiges der Compiler ausrechnen kann :-) wie z.B. ldi R16, (2+3+4+5+6) aber das ist nicht der fall bei mir. Ich habe mich oben verschrieben. Die Zahl sollte heissen (50*10^6)/(2^32). Und wenn du sagst erst mal mit 50*10^6 mal nehmen, dann bekomme ich auf jeden Fall ueberlaeufe bis hoechstens 64 bit. Aber wenn mir jemand erklaert wie das geht, dann division durch 2^32 wird durch wegnahme von 32 unteren Stellen gemacht. So stelle ich mir das vor. Also, falls jemand damit schon gearbeitet hat. Es handelt sich hier um einen DDS chip von Analog Device AD9835. Da wird eine 32bit Zahl reingeschrieben (nenen wie das mal asl Frequenzcode), die der Frequenz am ausgang entspricht. Der Freq.code wird berechnet als (Quarzfrequenz/2^32)*Frequenz. Die Aufgabe ist Frequenz zu aendern und dabei auch anzeigen. Dabei wird der Code veraendert, dicht der tatsaechlicher Frequenzwert. Und dann steht das Problem Code->Frequenz Umwandlung Kann mir jemand helfen?
Du wirst nicht um eine 64-Bit-Multiplikationsroutine umhin kommen in diesem Falle. Literatur zu solchen Algorithmen gibt's ja genug, außerdem kannst Du in den Bibliotheken der freien C-Compiler Anleihe nehmen. Wenn Du wenigstens einen ATmega hättest (außer dem alten 103), dann wäre Dein Job einfacher, weil die zumindest 16 * 16 Bit schon in Hardware können, die muß man dann ,,nur noch'' kaskadieren. Die Division durch 2^32 bedeutet natürlich in der Tat, daß man die unteren 32 Bit des Ergebnisses einfach ignoriert. Irgendwann steht ein AD985x auch auf meiner Tagesordnung (liegt schon ein Weilchen in der Schublade), aber ich würde solcherlei Krimskrams dem Compiler überlassen und mich lieber der eigentlichen Arbeit zuwenden. ;-) Dafür würde ich mir aber ganz gewiß nicht von vornherein Hände und Füße festzurren, indem ich mich auf einen AT90S2313 festlege, zumal natürlich angesichts von Preis und Stromaufnahme der DDS-Chips keinerlei Argument mehr dafür spricht, ausgerechnet mit dem kleinsten AVR noch 64-Bit-Multiplikationen anzuwerfen... Ganz davon abgesehen, weniger Code als der Compiler wirst Du für die Multiplikation ohnehin kaum bekommen.
Hm.... auf jeden Fall vielen Dank...Jetzt bin ich auch der Meinung, dass der Compiler es besser machen kann. Ausserdem ueberlege ich mir die andere Loesung ohne Mulriplikation. Der 2313 ist zu schwach dafuer denke ich mal. Leider bin ich gezwungen einen 2313 zu nehmen, da es ein fertiges Geraet ist, was ich nur modernisieren will indem ich dort eine Frequenzanzeige einbaue.
"Der 2313 ist zu schwach dafuer denke ich mal." Aber nur, wenn Du statt des Quarzes höchstens 50Hz Taktfrequenz anlegst oder einige Millionen Multiplikationen je Sekunde durchführen willst. Ich weiß jetzt nicht, ob man heutzutage ausschließlich mit Taschenrechnern Mathematik gelehrt bekommt. Ich mußte in der Schule jedenfalls noch schriftlich rechnen lernen und später kam dann auch noch das Rechnen in anderen Zahlensystemen (z.B. Binärsystem) dazu. Beides kombiniert und schon weißt Du, wie man es mit jeder CPU machen kann, nur mit Schieben und Addieren. Ansonsten gibt es ja noch die 16Bit-Beispiele auf der Atmel-Seite. Und der AVR hat ja auch 32 Register, damit kann man den Algorithmus bequem mindestens auf 8Byte * 8Byte = 16Byte aufbohren, das sollte doch wohl reichen. Für den 8051 habe ich mal eine Arithmetikbibliothek geschrieben, die mit Pointern arbeitet, d.h. die kann maximal mit 80Byte großen Zahlen arbeiten. Peter
@peter dannegger Es gibt mir eine Hoffnung :) Ok. Alle Operationen kann man nur mit Addieren (bzw subtr.) machen. Es ist ja klar. Das problem ist die Geschwindigkeit. Wenn bei AVR so einen Befehl gibt wie Multiplikation, was auch in einem Takt durchgefuert wird, wieso soll ich wie der alte Konrad Zuse alles durch Addition machen. Ok... Ich gebe zu, dass im inneren des CPU es genau so per Addition funktionier. Ok. Ich versuche jetzt gerade mir klar zu machen wie die Rechnung in Binaersystem funkzioniert. Es ist nicht schwirig. Wenn ich was fertig kriege bzw. nicht kriege schreib ich hier. Und noch ne Frage. es gibt eine Behauptung, dass der Compiler das genauso machen wuerde wie ich, wenn ich selbst mir eine Assembler subroutine schreibe. Ist das so oder macht der Compiler den groeseren Code???
Die Binäre Multiplikation ist überhaupt nicht wild. Wenn Du in der Schule die Multiplikation von Hand gelernt hast - geht genauso. Als Beispiel eine 4 x 4 Bit Multiplikation: Man muß nur die "1001" bei jedem Schritt um 1 nach links shiften, und entweder addieren oder eben nicht. Eine 32 x 32 Bit-Multiplikation läßt sich in 32 Schritten erledigen, das klappt auch mit dem 2313. 1001 x 1101 ------------------- 1001 1 0000 0 1001 1 1001 1 -----1------------- 1110101 Der Compiler macht i.a. einen größeren Code, weil er nicht speziell angepaßten Code erzeugt, sondern auch Sonderfälle (negative Zahlen, Überträge, Fehlermeldungen bei Überlauf) berücksichtigen muß, während "von Hand" assembliert einige Sonderfälle von vornherein ausgeschlossen werden können. Allerdings sollen die Atmel-Compiler (sowohl C als auch Basic) ein recht geringes Overhead haben.
@thkais Stimmt, das verstehe ich. Und die ganze Multiplication ist ja nur AND operation :) Also, so werde ich vorgehen. Dann hat der Joerg Wunsch nur teilweise recht :) ...von seinem posting <b> Ganz davon abgesehen, weniger Code als der Compiler wirst Du für die Multiplikation ohnehin kaum bekommen. </b> Folgendes ist mir eingefallen. Wenn ich ne Frequenz z.B. 14000000(14Mhz) binaer darstellen will, dann brauche ich nur 24bit. In Bascom bzw. C kann man nur zwischen 16 und 32bit waehlen. Man sieht das glaube ich deutlich, wenn ich 10 variablen von 24bit brauche, dann verschwende ich min Bascom 10 byte... Ist ja nicht gut
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.