Gast
#4677859
Hallo. Mich würde Interessieren, wie der ATmega Divisionen von ganzen Zahlen ausführt. Und warum rundet der µc das Ergebnis von 15/16 (0,94) auf 0 und nicht auf 1?
|
Anzeige
|
Division ATmega
Gast
#4677859
Hallo. Mich würde Interessieren, wie der ATmega Divisionen von ganzen Zahlen ausführt. Und warum rundet der µc das Ergebnis von 15/16 (0,94) auf 0 und nicht auf 1? Gaat11 schrieb: > Und warum rundet der µc das Ergebnis von 15/16 (0,94) auf 0 > und nicht auf 1? Das hat nichts mit dem ATmega zu tun, sondern mit der Programmiersprache C. Bei Division von zwei Integer-Zahlen und Speicherung in einer Integer-Variablen wird nur der Integer-Teil gespeichert. Und das ist die Zahl vor dem Komma. Schlag einfach mal Dein C-Buch auf ... Kapitel Datentypen.
Gast
#4677864
Frank M. schrieb: > Das hat nichts mit dem ATmega zu tun, sondern mit der Programmiersprache > C. Bei Division von zwei Integer-Zahlen und Speicherung in einer > Integer-Variablen wird nur der Integer-Teil gespeichert. Und das ist die > Zahl vor dem Komma. > > Schlag einfach mal Dein C-Buch auf ... Kapitel Datentypen. Genau so war das. Danke für die schnelle Antwort. Gaat11 schrieb: > Hallo. > > Mich würde Interessieren, wie der ATmega Divisionen von ganzen Zahlen > ausführt. Und warum rundet der µc das Ergebnis von 15/16 (0,94) auf 0 > und nicht auf 1? Ich nehme an, Du programmierst in C bzw. C++? Da verhält sich die Integer-Division genau so: als Division ohne Rest, egal auf welcher CPU. Hallo, das macht der AVR nicht willkürlich, er hält sich damit an den C-Standard. Dabei werden ganzzahlige Divisionen nicht gerundet, sondern die Nachkommastellen abgeschnitten Gerundete Ergebnisse gehen so: Ergebnis = (Dividend + Divisor/2) / Divisor mfG N.G. Weil es bei ganzen Zahlen keine Rundung gibt. Du kannst allerdings vor der Division den halben Divisor addieren. https://www.mikrocontroller.net/articles/AVR-Tutorial:_Arithmetik8#Division Wenn Du integer gerundet rechnen willst, dann addiere vor der Division den halben Divisor auf: n n + d/2 --- -> gerundet: ---------- d d Die Division d/2 übersetzt der Compiler heutzutage nicht in eine aufwändige Division, sondern ersetzt sie durch einfaches Shift nach rechts. Viele Grüße, Stefan Stefan K. schrieb: > Die Division d/2 übersetzt der Compiler heutzutage nicht in eine > aufwändige Division, sondern ersetzt sie durch einfaches Shift nach > rechts. Nö, nur bei unsigned darf er das machen. -1 / 2 = 0 -1 >> 1 = -1
Gast
#4677896
Stefan K. schrieb: > https://www.mikrocontroller.net/articles/AVR-Tutor... > > Wenn Du integer gerundet rechnen willst, dann addiere vor der Division > den halben Divisor auf: > > n n + d/2 > --- -> gerundet: ---------- > d d > > Die Division d/2 übersetzt der Compiler heutzutage nicht in eine > aufwändige Division, sondern ersetzt sie durch einfaches Shift nach > rechts. > > Viele Grüße, Stefan Danke. Das werde ich mal versuchen. Ps: Ich benutze unsgiend Peter D. schrieb: > Nö, nur bei unsigned darf er das machen. Ja, da gebe ich Dir recht. Aber auch in diesem Fall wird er keine Division daraus machen, sondern am Ende eine Shift-Operation:
Das ist ein gutes Beispiel, warum man solche mathematischen Funktionen (heutzutage) den Compiler machen lässt. Gruß, Stefan
Gast
#4678277
>das macht der AVR nicht willkürlich, er hält sich damit an den >C-Standard. Selten so einen BLÖDSINN gelesen. Der AVR hält sich nur an seine eigenen Regeln!
Gast
#4678288
> Mich würde Interessieren, wie der ATmega Divisionen ... ausführt. Bezogen auf den 8bit Befehlssatz: Gar nicht. Er kann nur Integer Zahlen nur addieren, subtrahieren und schieben. Manche (aber nicht alle AVR') können außerdem Fließkommazahlen multiplizieren. Dividieren können sie nicht. Bezogen auf die Programmiersprache: Der Compiler zerlegt die Division in einfachere Teil-Operationen, die der Mikrocontroller kann. Im Prinzip so, wie man in der Schule auch das manuelle dividieren lernt. Am Besten ist, du schreibst das einfach mal in C oder C++ auf und lässt Dir vom Compiler ein Listing (*.lst Datei) erstellen. Dann siehst du den Assembler-Code, der dabei heraus kommt.
Gast
#4678290
Stefan K. schrieb: > Peter D. schrieb: >> Nö, nur bei unsigned darf er das machen. > > Ja, da gebe ich Dir recht. Aber auch in diesem Fall wird er keine > Division daraus machen, sondern am Ende eine Shift-Operation: > >
> Das ist ein gutes Beispiel, warum man solche mathematischen Funktionen > (heutzutage) den Compiler machen lässt. > > Gruß, Stefan Stimmt. Ein blöder ASM Programmierer würde wahrscheinlich sowas komisches wie lsr r19 ror r18 daraus machen. Viel zu wenig Zyklen! Und womit soll denn dann bitteschön der ganze Flash gefüllt werden?
Gast
#4678292
Was macht denn der Compiler wenn man unsigned int nimmt? Eventuell ist ja dieser "Code" dem signed geschuldet, obwohl es selten ein signed braucht. ASM Superprofi schrieb: > Stimmt. Ein blöder ASM Programmierer würde wahrscheinlich sowas > komisches wie > > lsr r19 > ror r18 > > daraus machen. Genau. Und dass -1/2 dann zu 32767 wird, daran stören sich nur haarspaltende Kleingeister. ASM Superprofi schrieb: > Was macht denn der Compiler wenn man unsigned int nimmt?
-->
Gast
#4678381
Gut, ich nehme meine Stichelei hiermit zurück ;)
Gast
#4678559
>Manche (aber nicht alle AVR') können außerdem Fließkommazahlen >multiplizieren. Also falls du den MUL Befehl meinst, der multipliziert keine Fließkommazahlen;) Antwort schreibenBitte melde dich an, um einen Beitrag zu schreiben. |
Anzeige
|