Von Thomas Grasel Die in der letzten Ausgabe gewonnenen Kenntnisse möchte ich nun, wie schon angekündigt, in das Demoprogramm SINUS einbauen. Es macht deutlich wie sich dadurch das Aussehen von Programmen wandeln kann. program sinus3 var si,x: real n : integer function sinus(x: real n: integer): real var zw: real k : integer function fak(n: integer): real begin if n=1 then fak:=1 else fak:=n * fak(n-1) end (*---------------------------------*) function hoch(ba: real ex: integer): real begin if ex=1 then hoch:=ba else hoch:=ba*hoch(ba,ex-1) end (*---------------------------------*) begin zw:=x for k:=1 to n do zw:=zw + hoch(-1.0,k) * hoch(x,2*k+1) / fak(2*k+1) sinus:=zw end (*************************************) begin write('Wieviel Summierungen : ') readln(n) write('Welches Argument : ') readln(x) writeln si:=sinus(x,n) writeln('Sinus(', x:6:5, ') = ', sin(x):6:5) writeln writeln('Summenwert : ', si:6:5) writeln('Differenz : ', abs(si-sin(x)):6:5) end. In diesem Beispiel sind die Funktionen 'hoch' und 'fak' lokale Funktionen der Funktion 'sinus'. Diese erledigt jetzt die gesamte Rechenarbeit. Wenn man nun die drei Versionen von SINUS betrachtet kann man feststellen, daß die Berechnung des Sinus-Wertes immer mehr aus dem Hauptprogramm ausgelagert wurde. Ich gebe zu, SINUS1 ist am kürzesten, aber das war mir hier nicht so wichtig. Wichtig war, das Hauptprogramm möglichst kurz und übersichtlich zu gestalten. Wozu wird bei längeren Programmen noch deutlicher. Leider hat die Sache auch einen Haken. Bei SINUS3 dürfen maximal 4 Summierungen angegeben werden, sonst stürzt der Rechner ab. Vermutlich liegt das daran, daß der Rechner die vielen Rücksprungadressen, die bei der Rekursion auftreten, nicht mehr abspeichern kann, dies aber nicht erkennt! Die besten Ergebnisse liefert hier das Programm SINUS. Sein speziell für die Rechneranwendung ausgelegter Algorithmus erlaubt mehr als 50 Summierungen, also weit mehr als die Rechengenauigkeit des Rechners ist. Dies zeigt, daß das einfache Abschreiben von Formeln oft zu weitaus schlechteren Ergebnissen führt! Nun möchte ich ihnen ein Programm zur Nullstellenbestimmung von quadratischen Funktionen vorstellen. Es benutzt dazu im wesentlichen die pq-Formel, die hoffentlich bekannt ist. ------------- -p + ö(p)2 ö X = --- --ö(-) - q 1/2 2 - ö(2) program pq var a,b,c: real procedure nopq begin if b=0 then writeln('Keine Loesung !!!') else writeln('Loesung x=',-c/b:4:2) end (*-----------------------------------*) procedure pqformel var p,q,w: real procedure komplex var u,v: real begin u:=-p/2 v:=sqrt(-w) writeln('Loesung: x1=', u:4:2, ' + ', v:4:2, '*j') writeln('und x2=', u:4:2, ' - ', v:4:2, '*j') end procedure reel var x1,x2: real begin x1:=-p/2+sqrt(w) x2:=-p/2-sqrt(w) writeln('Loesung: x1=', x1:4:2) writeln('und x2=', x2:4:2) end begin p:=b/a q:=c/a w:=sqr(p/2)-q if w<0 then komplex else reel end (*-----------------------------------*) procedure eingabe procedure getzahl(var zahl: real koe : char) begin writeln write(koe, '=') readln(zahl) end begin getzahl(a,'a') getzahl(b,'b') getzahl(c,'c') writeln writeln(a:4:2,'x^2 + ', b:4:2, ' x + ', c:4:2, ' = 0') writeln end (*-----------------------------------*) procedure titel begin writeln(' ':8,'Nullstellenbestimmung') writeln writeln(' ':4,'Gleichung: ax^2 + bx + c = 0') writeln writeln(' Fuer den Pascal-Kurs des User-Mags') writeln(' ':9,'(c) 1992 Th.Grasel') end (*************************************) begin writeln(chr(125)) titel writeln eingabe (* Ueberpruefung ob pq-F. noetig *) if a<>0 then pqformel else nopq end. Das Hauptprogramm ist so kurz wie möglich gehalten, um die Übersicht nicht zu verlieren. Nach dem Start des Programms wird zur Prozedur 'titel' verzweigt. Hier wird erklärt, um was für ein Programm es sich handelt. Als nächstes wird dann zur Eingabe verweigt. Innerhalb dieser Prozedur werden die Zahlen a,b und c eingelesen. Dazu könnten 3 Abfragen dienen, oder wie im Programm, eine eigene lokale Prozedur verwendet werden. Sie bekommt zu Anzeigezwecken den Buchenstaben und die zugehörige Variable übergeben. Zum Abschluß von 'eingabe' wird noch einmal die Gleichung ausgegeben. Das Hauptprogramm testet nun ob die Variable 'a' Null ist. Ist dies der Fall kann die pq-Formel nicht verwendet werden und es wird zur Prozedur 'nopq' verwzeigt. Die zu bearbeitende Formel sieht nun folgendermaßen aus: bx + c = 0 Für diese Gleichung gibt es nur noch 2 mögliche Lösungen. Nämlich keine falls b=0 und c<>0, oder x=-c/b falls b<>0 ist. Dies wird in 'nopq' überprüft und das jeweilige Ergebnis ausgegeben. Ist a jedoch ungleich Null, so verweigt das Hauptprogramm zu 'pqformel'. Dort wird die Gleichung durch dividieren von 'a' auf die Form x^2 + px + q = 0 gebracht. In 'w' wird nun der Wert unter der Wurzel der pq-Formel geschrieben. Ist dieser negativ so ist die Lösung komplex. Um diese zu berechnen wird nun zu 'komplex' verzweigt und dort die Lösungen angezeigt. Ist der Wert unter der Wurzel positiv oder Null so ist die Lösung reel und es wird nach 'reel' zur Ausgabe des Ergebnisses verzweigt. Falls komplexe Zahlen nicht bekannt sein sollten, gilt folgendes: Taucht im Ergebnis irgendwo das 'j' auf, so hat die Gleichung kein Ergebnis im Reellen! So, ich hoffe ich habe die wichtigsten Punkte dieses Programmes erläutert. Es demonstriert sehr nachdrücklich wozu Prozeduren und lokale Prozeduren da sind. Wer meint das ganze ginge auch ohne diese, der kann das Programm ja mal ohne Prozeduren umschreiben. Ob man dann noch durch die vielen 'begin' und 'end's durchblickt wage ich jedoch zu bezweifeln! In der nächsten Ausgaben werde ich, zum Ausgleich zu der vielen trockenen Theorie der letzten Ausgaben, weitere nützliche Utilitys vorstellen.