Frage deutsch
~~~~~~~~~~~~~~
Wie berechne ich das Ergebnis eines Formelausdrucks, der als Textstring
eingegeben wird?
Wie berechne ich einen als String vorliegenden
Formelausdruck?
Question English
~~~~~~~~~~~~~~
How to calculate the result of a mathematical expression which has been
entered as a text string?
Antwort
~~~~~~~~
[ von Thomas Antoni und Olaf Deters, 12.06.2002 - 27.1.2004 ]
Hierzu benötigst Du einen sogenannten "Formula Solver" oder "Formula Parser"
, der den Text in Zahlen und mathematischen Operatoren zerlegt, die
entsprechende Berechnung durchführt und das Ergebnis bereitstellt.
Beim Programmieren des einfachen Taschenrechners für die MonsterFAQ ist mir
(Thomas Antoni) die folgende Idee gekommen: Mann müsste doch den Eingabestring
für eine beliebige Formel. z.B.
"(25^3) * sin(0.45)"
per Programm als QB-Quellsprache in eine externe BAS-Datei schreiben und
diese dann per CHAIN aufrufen, abarbeiten und das Ergebnis anzeigen lassen
können.
Beim obigen Beispiel würden die für die Eingabe der Formal und die Anzeige
des Ergebnisses zuständigen Befehle ganz einfach so lauten:
INPUT "y = "; Formel$ 'Formel eingeben
PRINT "y = "; (25^3) * sin(0.45) 'Formel berechnen und
anzeigen
Der letztere Befehl würde in die externe Datei geschrieben werden. Dann hätte
man auf einfachste Art einen sehr leistungsfähigen wissenschaftlichen
Taschenrechner realisiert.
Eine Schwierigkeit liegt darin, dass die meisten Anwender Winkel wohl im
Gradmaß und nicht in dem bei QBasic üblichen Bogenmaß eingeben möchten.
Dazu kann man im Formelstring ein "zahl°" durch "(Zahl * 6.28/360)"
ersetzen.
Das folgende Programm von Olaf Deters und mir setzt diese Idee
programmtechnisch in QBasic um:
'*****************************************************************
' FORMEL.BAS = Formel-Loeser in QBasic
' ==========
' ACHTUNG: Dieses Programm muss im Verzeichnis "C:\TEMP\" stehen.
' Bei einem anderen Verzeichnis muss man die Pfadvorgabe
' in der 2. Befehlszeile anpassen!
'
' FORMEL.BAS ist quasi ein wissenschaftlicher Taschenrechner.
' Es nimmt vom Anwender einen beliebigen Formelausdruck entgegen,
' berechnet dessen Ergebnis und zeigt es an.
'
' Der Formelausdruck muss der QBasic-Syntax entsprechen, mit einer
' Ausnahme: Die Eingabe von Winkeln kann auch in Grad statt im
' Bogenmass erfolgen. Dazu muss der Anwender hinter dem Winkel ein
' Gradzeichen "r" eingeben.
'
' Das Programm funktioniert nur als BAS-Datei und nicht als
' kompilierte EXE-Datei. Programmtechnisch ist das ganze so
' realisiert, dass das Programm den Formelstring in eine zweite
' externe BAS-Datei "Test.bas" schreibt. Ansschliessend wird
' die Kontrolle per CHAIN an Test.bas uebergeben. Test.bas
' berechnet die Formel, zeigt sie an und springt wiederum per
' CHAIN zurueck zum Beginn des Hauptprogramms.
'
' Der vom Windows-ANSI-Code abweichende DOS-ASCII-Zeichencode fuer
' das Grad-Symbol ist zu beachten.(ANSI: "°", ASCII: "r")
'
' (c) Olaf Deters u. Thomas Antoni, 26.1.2004 - 27.1.2004
'*****************************************************************
DECLARE FUNCTION Ersetze$ (F$)
COLOR 0, 7 'Schwarze Schrift auf hellgrauem Grund
WIDTH 80, 50 'VGA-Aufloesung mit 80 Spalten und 50 Zeilen
CLS
'
'---- Bedienungshinweise anzeigen -------------------------
'
PRINT
PRINT " ------======== F O R M E L - L O E S E R =======--------"
PRINT
PRINT " ________________Unterstuetzte Funktionen________________"
PRINT " a + b ..... Addition"
PRINT " a - b ..... Subtraktion"
PRINT " a * b ..... Multiplikation"
PRINT " a / b ..... Division"
PRINT " sqr(a) .... Quadratwurzel von a"
PRINT " a^b ....... Exponentialfunktion a hoch b"
PRINT " a^(1/b) ... allgemeine Wurzelfunktion b-te Wurzel aus a"
PRINT " log(a) .... Natuerlicher Logarithmus von a (zur Basis e)"
PRINT " sin(a) .... Sinus (a im Bogenmass)"
PRINT " cos(x) .... Cosinus (a im Bogenmass)"
PRINT " tan(a) .... Tangens (a im Bogenmass)"
PRINT " atn(x) .... Arcus Tangens (Winkel im Bogenmass)"
PRINT " ar ........ Winkel im Gradmass"
PRINT " hex$(a) ... Dezimal/Hexadezimal-Wandlung fuer a"
PRINT " val("; CHR$(34); "&ha"; CHR$(34); ")";
PRINT " Hexadezimal/Dezimalwandlung fuer a"
PRINT " MOD ....... Modulo-Division (liefert d.ganzzahligen Rest)"
PRINT " ========================================================="
PRINT " Beispielformel : (log(sin(30r))^2 + 1.4"
PRINT " ========================================================="
'
'---- Formel eingeben -------------------------------------
PRINT
PRINT
PRINT "Gib die gewuenschte Formel ein: "
PRINT
INPUT "y = ", F$
F1$ = Ersetze$(F$) 'Winkelangaben mit Gradzeichen ins Bogenmass
'umrechnen
'
'---- Formel in Datei Test.bas schreiben ------------------
'Es wird der folgende Quellcode geschrieben:
' PRINT "y = "; Fa$
' PRINT
' PRINT "[belieb.Taste]=Wiederholen";
' PRINT ".....[Esc]=Beenden"
' t$ = INPUT$(1)
' IF t$ = CHR$(27) THEN END
' CHAIN "c:\temp\formel.bas"
'Ausrufezeichen muessen als CHR$(34) geschrieben werden
'
OPEN "c:\temp\Test.bas" FOR OUTPUT AS #1
PRINT #1, "PRINT "; CHR$(34); "y = "; CHR$(34); ";"; F1$
PRINT #1, "PRINT"
PRINT #1, "PRINT "; CHR$(34); "[belieb.Taste]=Wiederholen"; CHR$(34); ";"
PRINT #1, "PRINT "; CHR$(34); ".....[Esc]=Beenden"; CHR$(34)
PRINT #1, "t$=input$(1)" ' Warten auf beliebige Taste
PRINT #1, "IF t$ = CHR$(27) THEN END"
PRINT #1, "CHAIN "; CHR$(34); "c:\temp\formel.bas"; CHR$(34)
'Ruecksprung zum Hauptmodul
CLOSE #1
'
'----- Test.bas aufrufen ----------------------------------
CHAIN "c:\temp\test.bas"
'
FUNCTION Ersetze$ (F$)
'----- Umrechnung Grad- in Bogenmass ----------------------
'----- ("Zahlr") -> ("Zahl * 2 * Pi / 360")
'Es wird im Formelstring nach einem Gradzeichen "r" gesucht.
'Steht davor eine Zahl, so wird das Gradzeichen durch
'den Teilstring "* 3.1415962# / 180" ersetzt.
FOR X = 1 TO LEN(F$)
IF MID$(F$, X, 1) = "r" THEN
Y = X
DO UNTIL MID$(F$, Y, 1) = "(" OR MID$(F$, Y, 1) = ")": Y = Y - 1
LOOP
L$ = LEFT$(F$, Y)
SELECT CASE VAL(MID$(F$, Y + 1, X - Y - 1))
CASE IS <> 0
M$ = STR$(VAL(MID$(F$, Y + 1, X - Y - 1)) * 3.1415962# / 180)
CASE IS = 0
M$ = " * 3.1415962# / 180"
END SELECT
R$ = RIGHT$(F$, LEN(F$) - X)
F$ = L$ + M$ + R$
F$ = Ersetze(F$)
END IF
NEXT X
Ersetze$ = F$
END FUNCTION
Das obige Programm steht im Verzeichnis Progs\ zur Verfügung sowie online
unter www.antonis.de/faq/progs/formel.bas .
Dieses Programm könnte man natürlich noch beliebig verbessern. Sinnvoll wäre
es z.B., alle auftretenden Fehler mit ON ERROR GOTO abzufangen. Dann werden
sämtliche Fehler wie nicht geschlossene Klammern, Division durch Null und die
Verwendung fascher Schlüsselwörter abgefangen, und das Programm könnte dann eine
ausagekräftige Fehlermeldung mit Neueingabemöglichkeit realisieren statt sich
sang- und klanglos zu beenden.
*** Weitere Formula Solvers
Ein guter Formular Solver stammt von Quinn Tyler Jackson . Diesem Programm
speist man eine mathematische Formel als Zeichenkette ein (z.B. "12 + 34^3")
ein. Das Ergebnis wird dann - ebenfalls als Zeichenkette ausgespuckt (z.B.
"39361") . Hiermit kannst Du bequem z.B. einen wissenschaftlichen Taschenrechner
aufbauen.
Der Formula Solver von Quinn Tyler Jackson steht unter Formula.zip auf
http://www.qbasic.de in der Rubrik
"QBasic -> Download -> Mathe" zum Herunterladen bereit.
[ The QBasic-MonsterFAQ --- Start Page: www.antonis.de/faq ]