Division ATmega

Moderator Persönliche Seite #4677861
Lesenswert?

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
Lesenswert?

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.
#4677881
Lesenswert?

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
Gast #4677896
Lesenswert?

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
Lesenswert?

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
Lesenswert?

> 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
Lesenswert?

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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren