Häufig stellt sich in Programmen für Mathematik und Wissenschaft das Problem der direkten Eingabe von Funktionen und Formeln während der Programmlaufzeit. Viele Programmierer scheuen davor zurück, entsprechende Routinen zu schreiben und umgehen das Problem auf mehr oder minder elegante Weise. Oft fehlt es nur am Know-how. Dabei ist ein guter Formelinterpreter mit relativ einfachen Mitteln zu bewerkstelligen. Einem Formelinterpreter kommt im wesentlichen die Aufgabe zu, mathematische Formeln aller Art nach den gültigen Regeln zu berechnen und das Ergebnis auszugeben. Ein guter Interpreter sollte die Verschachtelung nahezu beliebig vieler Klammerebenen erkennen, die Rechenoperationen in der vorschriftsmäßigen Reihenfolge durchführen, etc.
In diesem Beitrag stellen wir Ihnen eine elegante Lösung in ST Pascal 2.0 vor. »Formula« ist aufgrund seiner übersichtlichen Struktur und Universalität leicht in eigene Programme einzubinden. Wegen seines Umfangs finden Sie es nur auf der Leserservicediskette.
Der hier vorgestellte Formelinterpreter verarbeitet zunächst ausschließlich mathematische Formeln, die sich aus Zahlen, Operatoren und Klammerebenen, nicht aber aus Variablen zusammensetzen. Die direkte Verarbeitung von Funktionen ist nicht vorgesehen, um den vielseitigen Einsatz nicht zu gefährden. Formula ist durch diese Einschränkung ungleich vielfältiger. Das mag wie ein Widerspruch klingen. Tatsache ist aber, daß sich die Routine ohne weiteres als Funktionsinterpreter und für viele andere Aufgaben einsetzen läßt. Doch auch dazu später mehr.
Zunächst wollen wir Arbeitsweise und Einsatz des Formelinterpreters näher betrachten. Dessen zentrale Funktion heißt schlicht »FORMEL«. Sie erhält per Übergabe, wie schon erwähnt, einen String ohne Variablen mit den gewünschten Berechnungen.
Erlaubt sind alle deklarierten Funktionen, beliebig viele Klammerebenen und selbstverständlich die vier Grundrechenarten sowie eine Potenzen-Funktion. Der resultierende Wert ist vom Type Real. Die in der Prozedur Formel deklarierten Funktionen sind EXP, LN, SIN, COS, ARCTAN, ABS, SQR, SQRT, TAN und SIGN. Die Funktionen TAN und SIGN gehören nicht zum Pascal-Standard (das Programm entstand in ST Pascal Plus 2.0) und sollen verdeutlichen, daß sich der Formelinterpreter mühelos um beliebige Funktionen einer Variablen erweitern läßt.
Die Verwendung als Funktionsinterpreter gestaltet sich einfach, ist aber ein wenig umständlich. Eventuell zu übergebende Variablen übersetzt das Programm vor der Übergabe an den Formelinterpreter durch Zahlen. Damit keine Verwechslungen auftreten, wird beispielsweise die Variable »x« zuvor durch ein unverwechselbares Zeichen ersetzt. Zu diesem Zweck springt die Prozedur »UEBERSETZE« ein. Die Übersetzung ist notwendig, um zu verhindern, daß zum Beispiel alle Buchstaben »x« durch die Zahl ersetzt werden. So tritt ein »x« unter anderem in »exp« auf. Das Ersetzen der Zeichen nimmt die Prozedur ERSETZE_ZEICHEN vor.
Zu beachten ist, daß alle Funktionsnamen und Variablen klein geschrieben sind. Andernfalls muß vorher eine kleine Routine die großen Buchstaben in kleine umwandeln.
Formula führt einige grundlegende Fehlerabfragen durch. Es prüft jedoch nicht auf Gültigkeit der übergebenen Funktionen. Diese Überprüfung ist aus Zeitgründen entfallen.
Die Benutzung von FORMULA gestaltet sich einfach. Die Formel ist als String zu übergeben, Formula liefert das Ergebnis prompt zurück. Bei der Verwendung als Funktionsinterpreter ist die einmalige Übersetzung des Strings und eine leicht erweiterte Funktionsroutine hinzuzufügen. Ein Ausdruck eines Probelaufes mit dem Zusatzprogramm ist im Bild zu sehen.
Kommen wir nun zur Arbeitsweise unseres Moduls. Pascal verfügt über eine durchaus bemerkenswerte Eigenschaft: die Rekursion. Von dieser Fähigkeit einzelner Routinen, sich gegenseitig oder selbst aufzurufen, macht Formula ausgiebig Gebrauch.
Vereinfacht gesagt zergliedert es jede Formel so lange in Teile, bis Symbole und Zahlen getrennt vorliegen. Dazu werden zusammenhängende Teile (etwa durch Klammerung) immer wieder der Routine selbst übergeben, bis die Trennung vollständig ist. Ein primitives Beispiel mag dies verdeutlichen: »1 + 2«. Diese Formel zerlegt Formula an der Stelle mit dem Rechensymbol in die Teile T, ’2’ und ’ + ’ und übergibt sie wieder der Prozedur FORMEL. Nun ist kein Rechensymbol mehr vorhanden und FORMEL liefert 1 beziehungsweise 2 zurück. Das Programm verknüpft nun beide Zahlen anhand der brachliegenden Operation. Schließlich steht das Ergebnis fest: 3. Der Vorgang mag in dieser Form ein wenig abstrakt erscheinen, wird aber bei der Anwendung des Verfahrens auf umfangreiche Formeln deutlich.
Bei der Reihenfolge der Zergliederung sind einige Regeln zu beachten. Das gilt schon für die Grundrechenarten. Die Rangfolge »Punktrechnung geht vor Strichrechnung« ist einzuhalten. Deshalb sucht das Programm zuerst nach Rechensymbolen für Strichrechnung: » + « und »-«. Sind keine »Strichoperationen« mehr auszumachen, startet die Suche nach den Symbolen der Punktrechnung: »*« und »/«. Zuletzt sind die Potenzen an der Reihe.
Die Grundrechenarten sollen uns nicht reichen. Wer allerdings nur Grundrechenarten wünscht, kann die Teile für Funktionen und Klammerebenen aus der Prozedur FORMEL streichen und erhält eine recht kurze Prozedur.
Nun aber zu den Funktionen und Klammerebenen. Hinter einem Funktionsnamen soll das Argument in Klammern stehen. Da diese Vereinbarung leicht zu einer Verwechslung mit den regulären Klammerebenen führt, berechnet Formula die Funktionen zuerst. So erhält die Prozedur »BERECHNE_FUNKTION« nacheinander alle Funktionsnamen. BERECHNE_FUNKTION ermittelt das Argument der jeweiligen Funktion, indem sie das Argument als eigenständige Formel rekursiv an die Prozedur FORMEL übergibt. Anschließend erhält die jeweilige Funktion ihr Argument zurück. Daraufhin verschwindet der Name im String. An seine Stelle tritt der er rechnete Wert.
Als Beispiel lassen wir Formula den Ausdruck »1 + abs(-24)« berechnen. Hier taucht die Funktion ABS auf, die den Betrag einer Zahl bestimmt. Formula berechnet das Ergebnis aus »-24« und weist es der Absolutfunktion zu. Das Resultat nimmt den Platz des Funktionsaufrufes ein. Schließlich sieht der zu berechnende String so aus: »1 + 8«, eine einfache Formel.
Analog verfährt Formula mit den Klammerebenen. Es sucht zuerst eine gültige Klammer »(« und dann den passenden Partner »)«. Alles was dazwischensteht, erhält die Routine FORMEL — wiederum per Rekursion. Das Ergebnis ersetzt dann die Klammer. Die Anzahl der Klammerebenen sind somit nur durch die Rekursionstiefe der Pascal-Routine und damit nur durch den Speicher des ST beschränkt.
Die Funktion FORMEL enthält in der hier vorgestellten Fassung acht verschiedene Fehlermeldungen. Das reicht von der Division durch 0, bis hin zu fehlerhaft gesetzten Klammern.
Für den Einsatz als Formelinterpreter sind vor der Übergabe der Formel alle Variablen durch entsprechende Zahlen zu ersetzen. Damit läßt er sich ohne viel Aufwand auch als Funktionsinterpreter für Funktionen von mehreren Variablen oder für Berechnungen mit komplexen Zahlen einsetzen.
Mit Formula werden Sie Ihren ST noch besser und einfacher programmieren. Insbesondere in mathematischen und naturwissenschaftlichen Disziplinen kann Ihnen unser Modul viele nützliche Dienste erweisen. Ob für einfache Kurvendiskussionen, für numerische Rechenverfahren oder Anwendungen im Bereich »Messen Steuern, Regeln«, Formula stellt seine universellen Eigenschaften gern unter Beweis. Übrigens: Ihre eigenen Erweiterungen zu Formula interessieren auch andere Leser des ST-Magazins. Scheuen Sie sich also nicht, uns Ihre Erweiterungen auf Diskette zuzusenden. (mr)
Name: Formula
Autor: Dietmar Rabich
Sprache: ST-Pascal 2.0
Hardware: Monochrommonitor erforderlich
Funktion: Mathematischer Formelinterpreter
Besonderheit: wegen des großen Umfangs nur auf Leserservicediskette erhältlich