www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik integer durch 10 teilen


Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi, gibts nen trick, wie man ohne division (durch bitmanipulation) 
integervariablen schnell durch 10 teilen kann?
(AVR atmega)

ich meine so wie man mit 10 multiplizieren kann mit (x<<3) + (x<<1)

Autor: Harald aus Erlangen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
einfach mit 12,8 multiplizieren und 7 bits weglassen.

12 ist einfach: x2 x2 x(2+1)

0,8 sind 4/5

Autor: Ladde (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenns nicht hunderprozentig genau sein muss könnt man z.B. mit 51 
multiplizieren ((x<<5)+(x<<4)+(x<<1)+x) und anschließend um 9 bits 
schieben (also durch 512 teilen).
Wäre dann ne Division durch ca. 10,04.

Autor: Mark Brandis (markbrandis)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Neulich gab's hier mal einen Link, den ich leider grad nicht finde. Da 
war ein Xtreme Assembler Frickler ;-) am Werk der an der Division so 
lange geschraubt hat bis sie beinah mit einem halben Assembler-Befehl 
erledigt war...

Autor: Vlad Tepesch (vlad_tepesch)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
@ Harald aus Erlangen
du bist lustig.
wenn ich durch 5 teilen könnte, könnt ich auch durch 10 teilen

@Ladde:
as ganze sollte schon genau sein.

für die mult-shift-variante hatte ich mir mal ein script geschrieben 
(anhang, falls es interessiert), dass spuckt folgendes aus:

( x * 1 ) >> 3 = x * 0.125
( x * 1 ) >> 4 = x * 0.0625
( x * 3 ) >> 5 = x * 0.09375
( x * 7 ) >> 6 = x * 0.109375
( x * 13 ) >> 7 = x * 0.1015625
( x * 25 ) >> 8 = x * 0.09765625
( x * 51 ) >> 9 = x * 0.099609375
( x * 103 ) >> 10 = x * 0.1005859375
( x * 205 ) >> 11 = x * 0.10009765625
( x * 409 ) >> 12 = x * 0.099853515625
( x * 819 ) >> 13 = x * 0.0999755859375
( x * 1639 ) >> 14 = x * 0.10003662109375
( x * 3277 ) >> 15 = x * 0.100006103515625
( x * 6553 ) >> 16 = x * 0.09999084472
...

Auf dem weg gibts also nix, was so richtig passt.
bzw, die die genau genug sind, brauchen sehr große Zahlen 
(->Bibliotheksfunktionen), das heißt es führt das ganze schon ad 
absurdum, da man dann auch gleich ein /10 machen kann

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

Autor: Magnus Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mark Brandis schrieb:
> lange geschraubt hat bis sie beinah mit einem halben Assembler-Befehl
> erledigt war...

Alles wird gut...

Hat dein Pfleger gerade Pause?  ;o)

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@A. K.
danke, sieht nett aus

Autor: Anon Ymous (avion23)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schöner Link, ist jetzt in den bookmarks. Danke.

Autor: Ladde (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für 8-bit Integer-Zahlen bekommt man mit folgenden Formeln exakte 
Ergebnisse:
((x+1)*51)>>9 (immer abgerundet)
((x+6)*51)>>9 (ab 0,5 aufgerundet)

Gruß,
Ladde

Autor: Vlad Tepesch (vlad_tepesch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
üblicherweise wird bei integer division abgerundet.

Das ist essentiell, wenn man zahlen dezimal anzeigen will, da man den 
rest darstellt und mit der übrigen zahl die operation wiederholt, um die 
höheren Dezimalstellen anzuzeigen.


das ist wohl der resultierende code der für 8bit richig rechnet.
;-----------------------------------;
; RETRO (SYNTHETIC) DIVISION BY 10  ;
; ANSWER IN R1, R0=REM, A:PRESERVED ;
;-----------------------------------;
DIV10:  PUSH B
        LDI  B,26   ;MUL BY 26
        MUL  A,B    ;R1=A/10
        PUSH R1     ;BRUTE-FORCE CALC OF REMAINDER     
        LDI  B,10   ;CALC REM
        MUL  R1,B   ;R0=10xR1(QUOT)
        POP  R1     ;RESTORE QUOT
        SUB  R0,A   ;SUBTRACT REMx10
NODJST: NEG  R0     ;MAKE POSITIVE
         BRPL NONEG ;STILL NEG?
        ADD  R0,B   ;OOPS MAKE
        DEC  R1     ;ADJUSTMENTS
NONEG:   RET 

habs noch nich nicht verifiziert. sieht aber erst mal logisch aus

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mein Vorschlag für 8-Bit unsigned Division durch 10 für Assembler bzw 
avr-gcc Inline-Assembler:
uint8_t div10 (uint8_t x)
{
    uint8_t y;
    asm("mul  %1, %2"               "\n\t"
        "lsr  %1"                   "\n\t"
        "add  %1, R0"               "\n\t"
        "mov  %0, R1"               "\n\t"
        "clr  __zero_reg__"         "\n\t"
        "adc  %0, __zero_reg__"     "\n\t"
        "subi %1, lo8(-25)"         "\n\t"
        "sbci %0, hi8(-25)"         "\n\t"
        : "=d" (y), "+d" (x)
        : "d" ((unsigned char) 25));
    return y;
}

Autor: Alexander Schmidt (esko) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ladde schrieb:
> Wenns nicht hunderprozentig genau sein muss könnt man z.B. mit 51
> multiplizieren und anschließend um 9 bits schieben

Vlad Tepesch schrieb:
> @A. K.
> danke, sieht nett aus
> @Ladde:
> as ganze sollte schon genau sein.

Der Link von A.K. Beschreibt die Methode von Ladde.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.