Runden einer Division in ASM

Gast #345264
Lesenswert?

Hallo liebe (AVR-)ASM Freunde,

ich habe mich soeben an einem Problem festgefressen und sehe den Wald
vor lauter Bäumen nicht mehr.

Mein Problem ist eine simple Division von 8(Bit) / 8(Bit) aber
gerundet.

Mal ein Beispiel:
190:39=4,871... --> gerundet = 5 !

So, die Divisionsroutine bringt mir die 4 als Hauptergebnis und als
ganzzahliger Rest = 34. Ich finde aber, wahrscheinlich vor lauter
Rechnen, keinen Ansatz damit das Hauptergebnis 4 auf 5(wegen Rundung)
verändert wird. Im Hinterkopf habe ich noch die Formel A=A+B/2! Mit der
probiere ich jetzt schon 1 Stunde rum, jedoch ohne gescheites Ergebnis.


Also ich bin schon richtig konfus und zweifle an meinen Fähigkeiten.
Mir fehlt irgendwie der entscheidende Schritt.

Gruß
  Stevko
Gast #345267
Lesenswert?

@romanua:

Die Lösung ist zwar richtig, aber bedenke das ich mich im 8-Bit-Bereich
aufhalte.

--> 2*190 = ? = > 8Bit

Ich progamiere in ASM und meines Wissens gab es dafür eine einfache
Lösung. Irgendwas mit Schieben und Rotieren, ich habe es schon mehrmals
hier gelesen und es war so simpel, das ich es nicht notiert habe. Nach
dem Motto: "Alles klar. Das ist ja so einfach!" Doch jetzt wo ich vor
dem Problem stehe, ist es klar wie Kloßbrühe.

Gruß
  Stevko
Gast #345268
Lesenswert?

Das stimmt, kannst du nur 6-bit machen. Wenn du einen Fehler in der
Rundung haben darfst, kannst Du die Methode von Benedikt mit 7-bit
einsetzen.

Nimm doch 16-bit Division. Schieben und Rotieren hoert sich nach
Multiword Arithmetic an, wenn so, dann doch mehr als 8-bit.
Gast #345277
Lesenswert?

Guten Morgen

und Danke für die Antworten.

@Peter:
Ja das ist es was ich gesucht habe. Also probieren wir es mal aus.

 190:39=4,871...

-> a0 = 4  (Intergebnis)
   b0 = 34 (ganzzahliger Rest)
   t0 = Hilfsvariable


  mov  t0, b0    ;T = B = 34
  lsr  t0    ;T / 2 = 17
  add  a0, t0    ;A = A + B / 2 -> 21 = 4 + 17

Ne so gehts nicht.
Oder muß man das vorher addieren?

-> a0 = 190
   b0 = 39
   t0 = Hilfsvariable

  mov  t0, b0    ;T = B = 39
  lsr  t0    ;T / 2 = 19
  add  a0, t0    ;A = A + B / 2 -> 209 = 190 + 19

     Division
      geschiebe + rotiere

   Ergebnis = 5,3 -> Int_5

Aha so gehts, da konnte ich mich ja tot-probieren. Ich habe immer nach
einer Lösung hinter der Division gesucht.
Der Nachteil dieser Lösung ist aber ein Überlauf, z.B. 250:20.

Gruß
  Stevko
Gast #345279
Lesenswert?

ich kapier immer noch nicht warum man das so kompliziert machen muß.
Wenn Divisor und Rest vorliegen, sind das doch nur drei Operationen.
Die 190 nochmal reinzunehmen ist völlig unnötig. Die "39" einmal
rechts schieben und mit der "34" vergleichen. wenn 34 wie hier größer
19 dann zum Ergebnis "4" eins addieren, sonst bleibts bei der 4
Gast #345281
Lesenswert?

@Christoph

habe nicht verstanden, wo du gleich mitreinnimmst zu "kleiner" oder
zu "groesser"

Dann dieses Beispiel:

6/4 ist 1 Rest 2

2 ist kleiner oder gleich INT(4/2)=2

also gerundetes Ergebnis = 1

stimmts?
Gast #345283
Lesenswert?

Peter,

Christophs 2 extra Schritte sollten einen Ueberlauf verhindern, wenn
man 8-bit eine ASM (int+rest) Routine hat, sind aber rechnerisch
falsch.

Meine 2 extra Schritte verhindern den Ueberlauf und sind rechnerisch
korrekt, meine ich

if B-Rst(A/B)=<Rst(A/B)
   Result:=Int(A/B)+1
elseif
   Result:=Int(A/B)

Hat jemand ein Beispiel, wo es ein falsch abgerundetes Ergebnis
liefert?
Gast #345285
Lesenswert?

Das mit 6/4 stimmt, ich muß doch vor dem Halbieren 1 addieren,
entsprechend einer Addition von 0,5 beim dezimalen Runden, das geht mit
INC Divisor am einfachsten, solange er unter 255 bleibt.
Für die 6/4 muß dann "kleiner als" bzw. "größer oder gleich" die
Grenze bilden, sonst stimmts immer noch nicht.
Gast #345287
Lesenswert?

und sogar mit Divisor 255 klappts, der INC setzt das Carryflag, beim
Halbieren durch rechtsschieben kommt das ins MSB runter, egibt
$80=128.
es ist auf keinen Fall mehr 16Bit-Arithmetik nötig, wenn die
eigentliche Division erledigt ist.
Von negativen Zahlen war in der Aufgabe nicht die Rede, mit
Zweierkomplementdarstellung wird alles etwas komplizierter
Gast #345289
Lesenswert?

So, habe jetzt wieder mal ein wenig Zeit. Mein Dank geht an Alle die
hier mitwirken. Wie Ihr seht ist es nicht so einfach gewesen aber mehr
Köpfe = mehr Ideen!

Der Vorschlag von Christph sieht doch ganz passabel aus. Werde Ihn
heute Abend mal testen. Jedenfall ist das Problem mit dem Überlauf
vorläufig vom Tisch.

Gruß
  Stevko
Gast #345290
Lesenswert?

@Divisor=r1
@Difference=r1
@Rest=r2
@Ergebnis=r3

SUB Divisor, Rest     ;Difference=Divisor-Rest
CMP Rest,Difference   ;Set Flags
BRLT Fertig           ;exit if Difference > Rest
INC Ergebnis
Fertig:

Ich werd verrueckt noch einmal. Das gehts doch schneller und richtiger
als mit rechtsschieben.

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