Division ATmega

Moderator Persönliche Seite #4677861
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.
#4677865
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.
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
#4677932
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:
1
  int n;   // Y + 3, Y +4
2
  int e;   // Y + 1, Y + 2
3

4
  e = n / 2;
5
     854:  2b 81         ldd  r18, Y+3  ; 0x03
6
     856:  3c 81         ldd  r19, Y+4  ; 0x04
7
     858:  33 23         and  r19, r19
8
     85a:  14 f4         brge  .+4        ; 0x860 <__stack+0x1>
9
     85c:  2f 5f         subi  r18, 0xFF  ; 255
10
     85e:  3f 4f         sbci  r19, 0xFF  ; 255
11
     860:  35 95         asr  r19
12
     862:  27 95         ror  r18
13
     864:  3a 83         std  Y+2, r19  ; 0x02
14
     866:  29 83         std  Y+1, r18  ; 0x01
Das ist ein gutes Beispiel, warum man solche mathematischen Funktionen 
(heutzutage) den Compiler machen lässt.

Gruß, Stefan
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:
>
>
1
>   int n;   // Y + 3, Y +4
2
>   int e;   // Y + 1, Y + 2
3
> 
4
>   e = n / 2;
5
>      854:  2b 81         ldd  r18, Y+3  ; 0x03
6
>      856:  3c 81         ldd  r19, Y+4  ; 0x04
7
>      858:  33 23         and  r19, r19
8
>      85a:  14 f4         brge  .+4        ; 0x860 <__stack+0x1>
9
>      85c:  2f 5f         subi  r18, 0xFF  ; 255
10
>      85e:  3f 4f         sbci  r19, 0xFF  ; 255
11
>      860:  35 95         asr  r19
12
>      862:  27 95         ror  r18
13
>      864:  3a 83         std  Y+2, r19  ; 0x02
14
>      866:  29 83         std  Y+1, r18  ; 0x01
15
>
> 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.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 10 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.