Buchempfehlung
Windows System Programming
Windows System Programming
Das Kompendium liefert viele interessante Informationen zur Windows-Programmierung auf Englisch. [Mehr Infos...]
FreeBASIC-Chat
Es sind Benutzer im FreeBASIC-Chat online.
(Stand:  )
FreeBASIC bei Twitter
Twitter FreeBASIC-Nachrichten jetzt auch über Twitter erhalten. Follow us!

Formel-Parser und Termberechnung

Projektzusammenfassung
Projekt-Maintainer:Redakteurnemored Projektseite angelegt:20.11.2014
Lizenzierung:MIT-Lizenz Letzte Bearbeitung:27.11.2014
Projektkategorie:Mathematik      [Zurück zur Übersicht]

Mit dem Parser können Rechenausdrücke ausgewertet werden. Der Rechenausdruck wird als String übergeben und kann die in FreeBASIC üblichen Rechenoperationen enthalten:

Aufgerufen wird der Parser über die Funktion Calculate.eval(evalString), also z. B.

Calculate.eval("2 + 3 * 4 - 1")

Allgemeines

Das Projekt steht unter der Externer Link!MIT-Lizenz.
Quellcode siehe Link ganz unten auf dieser Seite.
Rückmeldungen, Fragen u. ä. bitte im Forum unter Externer Link!http://forum.qbasic.at/viewtopic.php?t=8285#106378.

Einfache Rechenausdrücke

Zahlenwerte werden in der in FreeBASIC üblichen Form übergeben, auch die wissenschaftliche Schreibweise wird unterstützt. Allerdings werden Leerzeichen und Tabulatoren ignoriert und können zur Formatierung eingesetzt werden; einzige Ausnahme ist, dass bei der wissenschaftlichen Schreibweise kein Leerzeichen vor dem "e" stehen darf.

print Calculate.eval("99 999 999 + 1")

Der Rückgabewert ist standardmäßig DOUBLE (dies kann geändert werden, indem vor dem Einbinden der Bibliothek CALCULATE_DATATYPE mithilfe von #DEFINE mit dem gewünschten Datentyp belegt wird).
Tritt ein Fehler auf, so wird der Wert 0 zurückgegeben, außerdem wird die globale Variable Calculate.CalcError gesetzt.

Calculate.NoError                = 0
Calculate.ErrorNoValue           = 1
Calculate.ErrorMissingBracket    = 2
Calculate.ErrorMissingValue      = 3
Calculate.ErrorWrongDecimalPoint = 4
Calculate.ErrorWrongExponent     = 5
Calculate.ErrorIllegalSymbol     = 6
Calculate.ErrorNotANumber        = 7
Calculate.ErrorUndefinedFunction = 8
Calculate.ErrorUndefinedVariable = 9
Calculate.ErrorOverwriteFunction = 10
Calculate.ErrorIllegalValue      = 11

Bei einem weiteren Aufruf von Calculate.eval wird Calculate.CalcError wieder zurückgesetzt.

Variablen

Der Parser bietet die Möglichkeit, Variablen anzulegen und zu verwenden. Es gibt globale und lokale Variablen - globale Variablen werden mit Calculate.setVar angelegt und stehen für alle weiteren Aufrufe zur Verfügung. Zwei mathematische Konstanten werden gleich zu Beginn als Variablen angelegt:

Calculate.setVar "e",  2.718281828459045
Calculate.setVar "pi", 3.141592653589793

Sie können sofort für Berechnungen verwendet werden:

print Calculate.eval("sin (pi/2)"

Lokale Variablen werden direkt im Evaluationsstring festgelegt und gelten nur für diesen einen Aufruf. Wird eine globale Variable lokal überschrieben, so gilt der neue Wert nur für die Zeit des aktuellen Aufrufs.

Mehrere Anweisungen innerhalb des Evaluationsstrings werden durch Strichpunkt getrennt. Zurückgegeben wird nur der Wert der letzten Anweisung, jedoch können vorherige Anweisungen zur Definition von Variablen dienen.

print Calculate.eval("x=3; x^2")
print Calculate.eval("x=3; y=8-2*x; y^2")

Im letzten Beispiel wird y mit dem Wert 2 belegt; zurückgegeben wird y^2, also 4.

Rekursive Algorithmen

Über die globalen Variablen wäre auch die Umsetzung eines rekursiven Algorithmus möglich, etwa die Nullstellensuche über das Newton-Verfahren, wenn der Term der Funktion und ihrer ersten Ableitungen über die Benutzereingabe erfolgt. Beachte, dass dieses kurze Beispiel keine Abfangroutine für divergente Folgen besitzt!

' Bestimmung von sqr(2) mit dem Newton-Verfahren
dim as string f = "x^2 - 2", fStrich = "2*x"
dim as double x = 1, x2
dim as integer i = 0
print "x0 = " & x
do
  i += 1
  Calculate.setVar "x", x
  x2 = x
  x = Calculate.eval("x - (" & f & ")/(" & fStrich & ")")
  print "x" & i & " = " & x
loop until abs(x - x2) < .00000001

Es gibt natürlich "schönere" Terme zur Bestimmung von Wurzelwerten, dies soll aber mehr ein Beispiel für die allgemeine Verwendung des Newton-Verfahrens sein.

Bekannte Probleme

Gelegentlich treten bei DOUBLE-Berechnungen Unterschiede im Ergebnis des Parsers und der direkten Berechnung im Programm auf; diese bewegen sich im Bereich der letzten Nachkommastellen und sind durch die mehrfachen Zwischenspeicherungen der einzelnen Teilergebnisse begründet.

Bei "unsinnigen" Rechnungen (etwa Potenzen mit negativer Basis und negativem Exponenten) können ebenfalls unterschiedliche Ergebnisse auftreten.

Sollten weitere Probleme auftauchen, bin ich für Rückmeldungen sehr dankbar!

Dateimanager
Formel-Parser19.11.14 23:0024 kB