Ansatz (1.Teil)
Hallo!
So wie ich das sehe, brauchst Du nur genaue Rechenvorschriften und -Methoden für die Multiplikation (Potenzierung mit x), das Ziehen der Quadratwurzel, die Division und die Addition. Wie Du sicher weißt, ist mit 32 oder 64 Bit langen Variablen, wie sie halbwegs moderne Betriebssysteme bieten, nicht viel aufgeführt. Daher gilt es, eigene Verfahren und Algorithmen zu finden, die mehr Stellen in den Operanden „verkraften“.
Ich gehe im folgenden von Grundkenntnissen in der Programmierung mit einer gängigen Hochsprache aus.
Man bastelt sich einen Datentyp, der alle Stellen, welche dargestellt werden sollen, aufnehmen soll (also etwa eine Dezimalstelle/Byte oder weniger speicherintensiv eine Dezimalstelle/(4 bit)).
Jetzt muß man nur noch die Rechenoperationen mit diesen langen Datentypen aus den Grundoperationen des Prozessors „zusammenstöpseln“.
Addieren ist wohl das einfachste: Einfach ausführen, was man in der Volksschule tat, wenn es darum ging, 2 Zahlen zu addieren.
Multiplizieren von 2 n-stelligen Zahlen nach der Schulmethode ist schon aufwändiger: Es sind n*n=n^2 Multiplikationen und eine Addition nötig. Also: Die Multiplikation doppelt langer Zahlen dauert 4 mal so lange. Ist n entsprechend groß, ist der Rechenaufwand gigantisch.
Abhilfe schafft die Multiplikation nach Karatsuba:
Zerlegen wir die zu multiplizierenden 2n-stelligen Zahlen u und v in eine obere und untere Hälfte von je n Stellen, so ergibt sich mit u=(10^n)u1+u0 und v=(10^n)*v1+v0:
uv=((10^2n)+(10^n))*u1*v1+(10^n)*(u1-u0)*(v0-v1)+((10^n)+1)*u0v0
Wir haben also 3 Teilmultiplikationen und 6 Additionen, was viel schneller geht als n^2 Multiplikationen und 1 Addition wie bei der Schulmethode. Die 10^n und 10^2n können einfach durch Dezimalshifts erzeugt werden.
Dividieren von u/v läßt sich mit der Newtoschen Näherung zur Kehrwertberechnung durchführen:
u/v=(1/v)u, also eine Kehrwertbildung und eine Multiplikation.
Iterationsvorschrift:
Anfangswert: x0=1/v, x(k+1) steht für x mit Index k+1:
x(k+1)=x(k)+x(k)(1-v*x(k))
Dies wird solange durchgeführt, bis der Ausdruck x(k)(1-v*x(k)) im Rahmen der Rechengenauigkeit 0 ist.
Das Berechnen der Quadratwurzel geht mit einer weiteren Newtonschen Näherung:
Zunächst berechnet man den Kehrwert von SQRT(d) in der Form 1/SQRT(d) durch folgendes Iterationschema (Anfangswert: x0=1/SQRT(d)):
x(k+1)=x(k)+x(k)*(1-d*x(k)*x(k))/2
Dies wird solange durchgeführt, bis der Ausdruck x(k)*(1-d*x(k)*x(k))/2 im Rahmen der Rechengenauigkeit 0 ist.
Abschließend multipliziert man das Resultat noch mit d, um SQRT(d) zu erhalten.
Also damit solltest Du den Algorithmus für die Fibonacci-Zahlen hinkriegen.
Allerdings würde ich persönlich die Fibonacci-Zahlen gemäß ihrer Definition berechnen, was nur Additionen erfordert, die letzten 2 Drittel meiner seitenweisen Schreiberei also gar nicht erfordert:
F(n+2)=F(n+1)+F(n)
In Worten: Jede nachfolgende Fibonacci-Zahl ist die Summer ihrer beiden Vorgänger, wobei mit 0 und 1 begonnen wird.
Also: F(n)=0,1,1,2,3,5,8,13,21,34,…
Grüße und Glück auf
Safog
[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]