Schnelle Division durch 5

Gast #1431280
Lesenswert?

Hallo,

Bei Multiplikation gibt es einfache Tricks x*5=x*(4+1)=x<<2+x
Gibt es etwas vergleichbares für die Division?

Mein Ausgangsproblem ist: [hbyte][lbyte]:5
Mein Instructionset ist: PIC16

Ich habe zwar eine Routine geschrieben, aber sie nimmt mir
zu viel Speicher weg. Deswegen suche ich bessere/schnellere/
platzsparendere Varianten dafür. Wer kann mir helfen?

Grüsse, Daniel
Gast #1431330
Lesenswert?

Naja, weiß ja nicht, wofür Du die Division brauchst und vor allem weiß 
ich nicht, ob der PIC schnelle Multiplikationen kann, aber vielleicht 
kann man auch iterativ vorgehen:

Zu lösen: y=x/5

Entspricht: finde ganzzahliges y, so dass möglichst genau gilt: 5*y=x

Iteration:
y_0 = x >> 2

Fehler: e_i = x - 5*y_i
oder auch: e_i = x - y_i - (y_i<<2)

Korrektur:
y_i+1 = y_i + e_i>>2

Auf meinem Taschenrechner geht das auch mit dem groben initialen Wert 
mit maximal 6 Iterationen für Deinen 16-Bit Wertebereich. Ist natürlich 
sehr speziell, aber vielleicht ein Ansatz für Dein Problem.

Grüße,
 Stefan
Gast #1431346
Lesenswert?

@Marius:
Coole Idee. Ziemlich genau. Kann man vielleicht noch mit einer 
Korrekturtabelle ganz genau machen.

Was mir aber noch aufgefallen ist:
Sowohl Marius' als auch meinen Vorschlag kann man nicht mit reiner 
16-Bit Arithmetik für den gesamten Wertebereich umsetzen. Bei meinem 
Vorschlag muss man vorzeichenbehaftet rechnen (+1 Bit), bei Marius 
entstehen Zwischenergebnisse mit 19 Bit.

Wie gesagt: Hängt alles vom Einsatzzweck ab.

Grüße,
 Stefan
Gast #1431350
Lesenswert?

Den Vorschlag von Markus kann man noch weiter treiben, z.B.:

x*51/256,
x*819/4096
x*13107/65536

Im letzten Fall läuft das Ganze zwar auf eine 32bit Multiplikation 
hinaus, dafür steht am Ende das Ergebnis in den beiden ersten Bytes.

Gruß, Chris
Gast #1431356
Lesenswert?

Hallo! 51/256 ist noch eine bessere Iteration:
x merken in y
x mal 2 (einmal links schieben)
x+y (ist jetzt 3 mal ursprüngliches x) und wieder in y merken
jetzt x mal 16 (viermal links schieben) ergibt 48 mal ursprüngliches x
wieder x+y ergibt jetzt 51 mal ursprüngliches x
jetzt den LOW-Teil von x "wegwerfen" bedeutet geteilt durch 256
Gast #1431384
Lesenswert?

Hallo Leute!
Mir ist da ein Muster aufgefallen:

In Binärdarstellung ist 0.2=0.001100110011...
Und: 51d=110011b
Und: 819d=1100110011b
Und: (Ihr ahnt es schon) 13107d=11001100110011b

Damit kann man Marius' (und natürlich auch Chris') Formeln auch so 
schreiben: (wenn man annimmt, dass (x<<3)>>6 == x>>3, etc. [1])

y=(x>>3)+(x>>4)+(x>>7)+(x>>8)+(x>>10)+(x>>11)+... [2]

Also als Reihenentwicklung. Die Genauigkeit kann man dann so einstellen 
wie man's braucht.

Grüße,
  Stefan

[1] natürlich kann man die Rechnung so nicht ausführen, weil man die 
weggefallenen Nachkommabits mit aufsummieren muss
[2] Marius hat mit 13 statt mit 12 im Zähler gerechnet, weil er gerundet 
hat, aber für die Reihenentwicklung ist das unerheblich.

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