Frage

Ich arbeite an einem Mikro-Controller ohne Hardware-Multiplikation und Division. Ich brauche Software-Algorithmen für diese grundlegenden Operationen zu kochen, die eine gute Balance aus kompakter Größe und Effizienz sind. Mein C-Compiler-Port wird diese algos beschäftigt, nicht die der C-Entwickler selbst.

Mein Google-Fu so weit ist Aufdrehen meist Lärm zu diesem Thema.

Kann jemand Punkt mich zu etwas informativ? Ich kann add / sub und Schiebebefehle verwenden. Suche in einer Tabelle basiert algos könnte auch Arbeit für mich, aber ich bin ein wenig besorgt über so viel in die Back-End-Compiler pauken ... um, so zu sprechen.

War es hilfreich?

Lösung

Hier ist eine einfache Multiplikation Algorithmus:

  1. Starten Sie mit Bit ganz rechts Multiplikator.

  2. Wenn das Bit in dem Multiplizierer 1 ist, fügen Sie Multiplikand

  3. Shift-Multiplikanden mit 1

  4. Zum nächsten Bit in Multiplikator und gehen Sie zurück zu Schritt 2.

Und hier ist ein Divisionsalgorithmus:

  1. Wenn Divisor größer ist als Dividende, zu stoppen.

  2. Während Divisor-Register kleiner als Dividenden-Register, Verschiebung nach links.

  3. Shift-Teiler registrieren rechts um 1.

  4. Subtract Divisor von Dividenden-Registern registrieren und das Bit auf 1 in dem Ergebnisregister am Bit ändern, entspricht die Gesamtzahl der Schichten auf das Divisor-Register durchgeführt.

  5. Von vorn anfangen in Schritt 1 mit Divisor-Register in ursprünglichen Zustand zurück.

Natürlich werden Sie in einer Check setzen müssen von 0 zum Teil, aber es sollte funktionieren.

Diese Algorithmen sind natürlich nur für ganze Zahlen sind.

Andere Tipps

Meine Lieblings Referenz für Dinge wie diese, in Buchform:

http://www.hackersdelight.org/

Sie können auch nicht falsch mit TAOCP gehen: http: // www-cs-faculty.stanford.edu/~uno/taocp.html

Hier ist ein Divisionsalgorithmus: http: // www. prasannatech.net/2009/01/division-without-division-operator_24.html

Ich gehe davon reden wir über ints?

Wenn es keine Hardware-Unterstützung, müssen Sie Ihre eigene Division durch Null Ausnahme implementieren.

(Ich habe nicht viel Glück haben schnell eine Multiplikation Algorithmus zu finden, aber ich werde schauen halten, wenn jemand anderes einen nicht findet).

Eine einfache und recht performant Multiplikationsalgorithmus für ganze Zahlen ist Russische ländliche Multiplikation .

Für rationals, könnten Sie versuchen, eine binäre Zitat Notation , für die ist Teilung leichter als üblich.

Es stellt sich heraus, dass ich noch einige alte 68000 Assembler-Code für lange Multiplikation und Division lange haben. 68000 Code ist ziemlich sauber und einfach, sollte so einfach sein, für Ihren Chip zu übersetzen.

Die 68000 hatte Multiplikation und Division Anweisungen IIRC -. Ich denke, diese als Lernübung geschrieben wurden

Beschlossen, nur hier, um den Code zu setzen. Hinzugefügt Kommentare und in dem Prozess, ein Problem behoben.

;
; Purpose  : division of longword by longword to give longword
;          : all values signed.
; Requires : d0.L == Value to divide
;          : d1.L == Value to divide by
; Changes  : d0.L == Remainder
;          : d2.L == Result
;          : corrupts d1, d3, d4
;

        section text

ldiv:   move    #0,d3     ; Convert d0 -ve to +ve - d3 records original sign
        tst.l   d0
        bpl.s   lib5a
        neg.l   d0
        not     d3
lib5a:  tst.l   d1        ; Convert d1 -ve to +ve - d3 records result sign
        bpl.s   lib5b
        neg.l   d1
        not     d3
lib5b:  tst.l   d1        ; Detect division by zero (not really handled well)
        bne.s   lib3a
        rts
lib3a:  moveq.l #0,d2     ; Init working result d2
        moveq.l #1,d4     ; Init d4
lib3b:  cmp.l   d0,d1     ; while d0 < d1 {
        bhi.s   lib3c
        asl.l   #1,d1     ; double d1 and d4
        asl.l   #1,d4
        bra.s   lib3b     ; }
lib3c:  asr.l   #1,d1     ; halve d1 and d4
        asr.l   #1,d4
        bcs.s   lib3d     ; stop when d4 reaches zero
        cmp.l   d0,d1     ; do subtraction if appropriate
        bhi.s   lib3c
        or.l    d4,d2     ; update result
        sub.l   d1,d0
        bne.s   lib3c
lib3d:                    ; fix the result and remainder signs
;       and.l   #$7fffffff,d2  ; don't know why this is here
        tst     d3
        beq.s   lib3e
        neg.l   d2
        neg.l   d0
lib3e:  rts

;
; Purpose  : Multiply long by long to give long
; Requires : D0.L == Input 1
;          : D1.L == Input 2
; Changes  : D2.L == Result
;          : D3.L is corrupted
;

lmul:   move    #0,d3       ; d0 -ve to +ve, original sign in d3
        tst.l   d0
        bpl.s   lib4c
        neg.l   d0
        not     d3
lib4c:  tst.l   d1          ; d1 -ve to +ve, result sign in d3
        bpl.s   lib4d
        neg.l   d1
        not     d3
lib4d:  moveq.l #0,d2       ; init d2 as working result
lib4a:  asr.l   #1,d0       ; shift d0 right
        bcs.s   lib4b       ; if a bit fell off, update result
        asl.l   #1,d1       ; either way, shift left d1
        tst.l   d0
        bne.s   lib4a       ; if d0 non-zero, continue
        tst.l   d3          ; basically done - apply sign?
        beq.s   lib4e       ; was broken! now fixed
        neg.l   d2
lib4e:  rts
lib4b:  add.l   d1,d2      ; main loop body - update result
        asl.l   #1,d1
        bra.s   lib4a

übrigens - ich habe nie herausfinden, ob es notwendig wäre, alles zu positiv zu Beginn zu konvertieren. Wenn Sie vorsichtig mit dem Schichtbetrieb, dass vermeidbarer Kopf sein kann.

zu multiplizieren, addieren Teilprodukte von dem Multiplikanden an einen Akkumulator verschoben iff das entsprechende Bit in den Multiplizierer Satz ist. Shift Multiplikand und Multiplikator am Ende der Schleife, Test Multiplikator & 1 zu sehen, ob zusätzlich getan werden sollte.

Die Microchip PICmicro 16Fxxx Serie Chips haben keine multiplizieren oder dividieren Anweisung. einige der weichen Vielleicht vermehren und weiche divide Routinen für sie kann auf Ihre MCU portiert werden.

PIC-Mikrocontroller Grund Math Multiplikation Methoden

PIC-Mikrocontroller Grund Math Abteilung Methoden

Überprüfen Sie auch heraus "Newton-Verfahren" für die Teilung . Ich denke, dass Verfahren, die kleinste Größe der ausführbaren Datei eines Divisionsalgorithmus gibt, gebe ich je gesehen habe, obwohl die Erklärung macht es klingen komplizierter, als es wirklich ist. Ich höre, dass einige frühe Cray Supercomputer Newton-Verfahren für die Division verwendet.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top