Hi, wie der Titel schon beschreibt, versuche ich momentan als total blutiger Anfänger einen Dividierer zu schreiben. Ich habe vier Register r16, r17, r18 und r19. In diesen Registern habe ich eine einzige Zahl gespeichert, die durch 12 dividiert werden soll. Das höchstwertigste Register ist r19. Leider konnte ich bis jetzt nur Schleifen programmieren die die einzelnen Register dividiert haben bis eine Zahl über geblieben ist, die kleiner war als der Divisor. Mein Problem ist nun, dass diese Zahl ignoriert wird, wodurch mein Ergebnis zu ungenau wird. Z.B.: Ist in r19 die Zahl 11 gespeichert und wird durch 12 dividiert, kommt 0 raus und die 11 wird weggeschmissen. Wie kann man das nun lösen, dass die 11 weiter verwendet wird? Vielen Dank für deine Hilfe schon im voraus, Fabi
Fabian727 schrieb: > Wie kann man das nun lösen, dass die 11 weiter verwendet wird? Das kommt drauf an, wie Du möchtest, daß sie weiter verwendet wird. Wegschmeißen tust Du sie ja. Peter
ja, ich würde gerne die vier register dividieren (und als eine einzige Zahl verwenden), quasi wäre dann der Rest vom höheren Register dann das 9., 10., 22. etc. bit vom niedrigereren Register, aber leider kann ich die ja nicht einfach anhängen :D.
Deine Ausführungen werden immer konfuser. Vielleicht willst Du ja das: Multipliziere vorher mit 10, dann hat Dein Ergebnis eine gedachte Nachkommastelle. Peter
Hi >Leider konnte ich bis jetzt nur Schleifen programmieren die die >einzelnen Register dividiert haben bis eine Zahl über geblieben ist, die >kleiner war als der Divisor. Willst du jetzt aufrunden? Wenn ja, dann vergleiche den Rest einfach mit 6. MfG Spess
mein Problem ergibt sich durch folgendes: Ich habe meine clock0 in einem attiny 2313, jedesmall wenn es einen clockoverflow gibt, wird r16 incrementiert. Wenn r16 voll ist wird r17 danach r18 und dann r19 erhöht. Irgendwann kommt dann ein Interrupt, was die clock0 anhält. Jetzt will ich nach 1/12 der gemessenen Zeit die 1. LED anschalten, nach einem weiteren 12tel will ich die 2. LED anschalten und so weiter. Dafür brauch ich die Division. Aber mit deine Idee mit Register nach Links verschieben ist eine gute Idee, werde ich mal weiter nachverfolgen. Allerdings problematisch, wenn ich im Register 0xFF geladen habe und das dann verschiebe, weil ich dann die obersten 1er verliere.
Brauchst du wirklich 32bit Auflösung für die zu messende Zeit? In welchem Bereich (von - bis) liegen denn die zu messenden Zeiten? Für 32bit ist wohl die entsprechende Dividier-Routine von elm-chan die einfachste Lösung: http://elm-chan.org/docs/avrlib/div32.txt Die könnte man sicher noch kürzen, da dein Divisor ja in ein einzelnes 8bit-Register passt. Wenn es nicht absolut genau sein muss, könnte man auch mit 21 multiplizieren und dann das niederwertigste Register verwerfen. (x * 21 / 256 = x / 12,19...)
wie kommst du auf die zahl 21? Wie groß die zeit min und max ist, hab ich mir noch nicht so viele Gedanken gemacht. Aber ich habe festgestellt, wenn ich einfach so 11 / 12 teile und den rest wegschmeis, bleibt mir als ergebnis 0 über. Im "obersten / höchstwertigsten" Register ist das verdammt viel Zeit die ich wegwerfe, wodurch meine LED's zu früh angehen.
ich habe mir mal die vorgeschlagene 32-bit-divison angeschaut. Leider bin ich noch blutiger anfänger (mit maximal 30 h "erfahrung") und kann mit meinem Wissen diese Schleife noch nicht richtig deuten. Ich habe mir erlaubt meine Kommentare noch weiter rechts hinzuschreiben. Die bezifferten Kommentare sind fragen meinerseits, bzw versuchte Interpretationen, bei denen ich mein Wissen hingeschrieben habe, bei denen ich aber glaube, dass sie nicht richtig sind Die weiter rechts sind einfach nur Kommentare von mir, um den Programmcode soweit möglich zu verstehen. Bitte trotzdem wieder durchlesen und korrigieren. Bitte helft mir das zu verstehen. Und vielen dank für eure Hilfe bis hier hin. fabi
(1) don't care = egal ! und lc ist der Loopcounter 32 für eine 32Bit Division (2) siehe 1 (3) PC=Programmcounter PC+6 müsste dann zu <dec lc> springen, warum hier keine Marken verwendet werden ?? (4) wie 3 nur das wenn lc noch nicht 0 zu <lsl var10> gesprungen wird Sascha
vielen Dank für diene ekrlärung, hilft schon einiges weiter das programm zu verstehen
Fabian Scheidig schrieb: > Wie groß die zeit min und max ist, hab ich mir noch nicht so viele > Gedanken gemacht. Aber ich habe festgestellt, wenn ich einfach so 11 / > 12 teile und den rest wegschmeis, bleibt mir als ergebnis 0 über. Im > "obersten / höchstwertigsten" Register ist das verdammt viel Zeit die > ich wegwerfe, wodurch meine LED's zu früh angehen. Das kommt halt auf die Zeit drauf an. Wenn deine Register die Zeit in Millisekunden zählen, dann sind 11 Millisekunden nicht so wahnsinnig viel Zeit. Im übrigen. Ja natürlich. Das Problem hast du immer. Mathematiker nennen das das Schubladenargument: Es ist nicht möglich n Socken in m Schubladen zu verstauen, so dass in allen Schubladen gleich viele Socken drinnen sind. Es sei denn n ist ein ganzzahliges Vielfaches von m. So ist das nun mal, wenn man mit ganzen Zahlen hantiert. Da musst du dir was einfallen lassen, wie du die Situation handhaben willst.
soweit, ich die divisions-schleife verstanden hab, ist die einfach nur genial und ich werde sie verwenden. Mir ist klar, dass ich den allerletzten rest nicht verwenden kann, aber ich will halt den rest vom höchstwertigsten Register noch im 2.höchstwertigsten verwenden, weil sonst einfach irre viel zeit weg geht. Ich habs ausgerechnet, was für zeiten ich hab. Meine min:0,17 sec. und meine max: 1,7 sec. Jetzt muss ich sie nur noch bis zum ende durch verstehen und dann für mich modifizieren. Vielen Dank, weitere Proleme kommen sicher bald, vielen Dank noch mal an alle p.s. wo finde ich solche Schleifen? fab
Du kannst Deine 32-Bit Zahl mit 357913941 (auch 32 Bit) multiplizieren. Von dem 64-Bit Ergebnis schmeisst Du die unteren 32 Bit einfach weg. Evtl. verwendest Du von den unteren 32 Bit das MSB zum Runden. Gruß Jobst
Jobst M. schrieb: > Du kannst Deine 32-Bit Zahl mit 357913941 (auch 32 Bit) multiplizieren. > Von dem 64-Bit Ergebnis schmeisst Du die unteren 32 Bit einfach weg. > Evtl. verwendest Du von den unteren 32 Bit das MSB zum Runden. Auch wenn ich nicht der TO bin, interessiert mich dieses Thema auch gerade ziemlich und würde gern mal den Sinn hinter deinem geschriebenen verstehen wollen. Also wie kommst du auf die 357913941? MfG Dennis
Dennis H. schrieb: > wie kommst du auf die 357913941? 2^32 / 12 Du Multiplizierst also mit 1/12 und schmeisst die Nachkommastellen weg. Gruß Jobst
Jobst M. schrieb: > Dennis H. schrieb: >> wie kommst du auf die 357913941? > > 2^32 / 12 > > Du Multiplizierst also mit 1/12 und schmeisst die Nachkommastellen weg. > > > Gruß > > Jobst Das leuchtet sogar mir ein, das ist ja mal ein richtig interessanter Ansatz. Aber du lässt da sozusagen die Nachkommastellen einfach unter den Tisch fallen? Also wenn ich 2^32/12 rechne, habe ich ja nach dem Komma noch .33333..33 stehen. Vielen Dank für die gute Erklärung MfG Dennis
Eine genauere Auflösung als ein LSB hast Du eben nicht. Egal, ob Du teilst oder multiplizierst. Ich hatte ja auch vorgeschlagen, das MSB der unteren 32-Bit zum runden zu benutzen. Gruß Jobst
Hi Wo ist eigentlich das Problem? Du dividierst eine Zahl durch 12 und bekommst einen Rest von 0..11. Was willst du jetzt machen? War schon meine Frage hier: Beitrag "Re: [avrassembler] Division Problem mit Rest" MfG Spess
spess53 schrieb: > Was willst du jetzt machen? War schon > meine Frage hier: Nur, daß es nun eine andere Person ist ;-) Dennis H. schrieb: > Auch wenn ich nicht der TO bin ;-) Aber stimmt schon: Entweder rundest Du, schneidest ab, behältst einen Rest oder fügst Nachkommastellen an. Gruß Jobst
Jobst M. schrieb: > Eine genauere Auflösung als ein LSB hast Du eben nicht. Egal, ob Du > teilst oder multiplizierst. Stimmt schon, und bei einer 32Bit Zahl sollte das nicht so ganz ins Gewicht fallen. Ich glaube, in den seltensten Fällen benötigt man so genaue Berechnungen, schwierig wirds bloß, wenn man mit dem errechneten Wert noch lange weiter rechnet, weil sich dann der Fehler schnell potenziert. Aber trotzdem vielen Dank für die ehrlich gesagt sehr elegante Lösung, die gefällt mir richtig gut. MfG Dennis
Auch von mir vielen dank an alle, die mir weiter geholfen haben. Mein Problem war, dass ich vier Register durch 12 dividiert hatte und somit mir 4 mal ein Rest zwischen 0 und 11 übergeblieben ist. Wobei ich davon die "oberen oder höherwertigeren" Reste hätte noch verwenden können. Ich wusste aber nicht wie. Mit der 32-Bit-Division, die oben als Textanhang dabei ist, hat sich mein problem gelöst und der letzte Rest kann einfach verfallen. Vielen Dank noch einmal an alle, fabi
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.