08/2008 - KaffeeKlatsch
08/2008 - KaffeeKlatsch
08/2008 - KaffeeKlatsch
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
Des Programmierers kleine Vergnügen<br />
Genug der Basis-Mathematik, wir sind ja auf der Suche<br />
nach einem effizienten Algorithmus. Zur Berechnung<br />
von n m brauchen wir also m - 1 Multiplikationen. Wer<br />
also auf diese Art n 16 berechnen möchte benötigt 15 Multiplikationen.<br />
Nutzt man allerdings aus, dass 16 = 2 4 ist,<br />
und berechnet:<br />
x 1 = n * n; // n 2<br />
x 2 = x 1 * x 1; // (n 2 ) 2 = 2 4<br />
x 3 = x 2 * x 2; // ((n 2 ) 2 ) 2 = (2 4 ) 2 = 2 8<br />
x 4 = x 3 * x 3; // (((n 2 ) 2 ) 2 ) 2 = ((2 4 ) 2 ) 2 = (2 8 ) 2 = 2 16<br />
Wir benötigen so nur 4 Multiplikationen. Als Exponenten<br />
eine Zweierpotenz zu haben ist allerdings ein<br />
recht spezieller Fall, sodass wir der Frage nachgehen, wie<br />
sich das Vorgehen verallgemeinern lässt.<br />
Das Horner-Schema<br />
Dem einen oder anderem Leser ist aus dem Mathematikunterricht<br />
wahrscheinlich noch das Horner-Schema [3]<br />
bekannt 1 , mit dem Polynome effizient ausgewertet werden<br />
können. Üblicher Weise ist ein Polynom als Summe<br />
von absteigenden Potenzen einer Variablen gegeben:<br />
7 x 4 + 3 x 3 + 9 x 2 + 2 x + 4.<br />
Berechnet man das Ergebnis, indem man diese Summe<br />
von vorne nach hinten abarbeitet, so benötigt man<br />
im obigen Fall vier Additionen und zehn Multiplikationen.<br />
Dass hierbei viel Rechenarbeit unnötig verrichtet<br />
wird, ist klar erkennbar, wenn man betrachtet, wie oft<br />
die Potenzen von x berechnet werden. x 2 wird dreimal<br />
berechnet, für den ersten, zweiten und den dritten Summanden.<br />
x 3 wird ebenfalls unnötiger Weise zweimal berechnet.<br />
Durch einfaches Umsortieren und geeignete Klammersetzung<br />
können solche unnötigen Rechenschritte<br />
völlig eingespart werden. Die Gleichung lautet dann:<br />
(((7 x + 3) x + 9) x + 2) x + 4.<br />
Die bereits berechneten Potenzen von x werden so immer<br />
weiter verwendet. Dabei benötigt man zwar weiterhin<br />
vier Additionen, aber jetzt nur noch vier Multiplikationen.<br />
Durch Ausklammern und Sortieren nach<br />
Potenzen lässt sich die Äquivalenz der beiden Darstellungen<br />
überprüfen. Diese Umformung, welche die Anzahl<br />
der nötigen Multiplikationen reduziert, 2 ist nicht an<br />
1<br />
Wenn Sie nicht dazu gehören: Nicht traurig sein! Eine quasi-statistische Umfrage<br />
in meinem direkten Umkreis hat ergeben: kaum ist das Studium ein paar<br />
Jahre her, erinnert sich daran keiner mehr.<br />
2<br />
Und nebenbei bemerkt dadurch bei Fließkommazahlen, wegen weniger Rundungsfehler,<br />
deutlich bessere Ergebnisse liefert.<br />
eine spezielle Eigenschaft des Polynoms gebunden, außer<br />
dass die Exponenten ganzzahlig sein sollten.<br />
Mit einem ähnlichen Prinzip können wir auch unser<br />
Potenzierungsproblem lösen, indem wir bei allen<br />
Rechen operationen sozusagen eine Stufe höher gehen:<br />
Aus Addition wird Multiplikation und aus Multiplikation<br />
wird Quadrierung.<br />
Wollen wir zum Beispiel n k mit k = 29 berechnen, so<br />
zerlegen wir 29 zunächst in seine Binärdarstellung:<br />
29 = 11101 2 = 1 * 2 4 + 1 * 2 3 + 1 * 2 2 + 0 * 2 1 + 1 * 2 0 .<br />
Diese Gleichung, entsprechend des Horner-Schemas<br />
umgewandelt, lautet:<br />
(((((((1 * 2) + 1) * 2) + 1) * 2) + 0) * 2) + 1<br />
= (((((( 2) + 1) * 2) + 1) * 2) * 2) + 1.<br />
n 29 schreiben wir damit um als<br />
n (24 + 2 3 + 2 2 + 2 0) =<br />
n (((((((2 + 1) * 2) + 1) * 2) + 0) * 2) + 1) .<br />
Zerlegt man diese Darstellung, 3 so erhält man:<br />
n ((((((2 + 1) * 2) + 1) * 2) + 0) * 2) * n<br />
= (n (((((2 + 1) * 2) + 1) * 2) + 0) ) 2 * n<br />
= (n ((((2 + 1) * 2) + 1) * 2) ) 2 * n<br />
= ((n (((2 + 1) * 2) + 1) ) 2 ) 2 * n<br />
= ((n ((2 + 1) * 2) * n) 2 ) 2 * n<br />
= (((n (2) * n) 2 * n) 2 ) 2 * n.<br />
Dies wiederum entspricht einer Aneinanderreihung von<br />
einigen, aber deutlich weniger, Multiplikationen und<br />
Quadrierungen: In diesem Fall benötigen wir 4 Quadrate<br />
und 3 Multiplikationen, also nur 7 statt 28 Multiplikationen.<br />
So wie es aussieht kann man die Potenz durch Auflösung<br />
von rechts problemlos berechnen. Ist die letzte<br />
Binärziffer des Exponenten k eine 1, so multiplizieren<br />
wir den verbleibenden Ausdruck mit n. Sind wir noch<br />
nicht bei der letzten Ziffer angekommen, so muss der<br />
verbleibende Rest auf jeden Fall quadriert werden. Ist die<br />
nächste Ziffer eine 0, so muss nichts gemacht werden,<br />
außer natürlich, dass für den verbleibenden Rest wieder<br />
quadriert werden muss, usw. Dies können wir rekursiv für<br />
die einzelnen Ziffern von k machen, indem wir die letzte<br />
Ziffer von k testen und diese anschließend durch ein<br />
Shift verschwinden lassen. Es gibt dann nichts Weiteres<br />
3<br />
Und dabei gelten die Beziehungen für Potenzen von Potenzen (n a ) b = n (a*b) und<br />
für Multiplikationen von Potenzen n a * n b = n (a+b) .<br />
Seite 20 <strong>KaffeeKlatsch</strong> Jahrgang 1 / Nr. 8 / August 20<strong>08</strong>