07.11.2014 Aufrufe

08/2008 - KaffeeKlatsch

08/2008 - KaffeeKlatsch

08/2008 - KaffeeKlatsch

MEHR ANZEIGEN
WENIGER ANZEIGEN

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>

Hurra! Ihre Datei wurde hochgeladen und ist bereit für die Veröffentlichung.

Erfolgreich gespeichert!

Leider ist etwas schief gelaufen!