Hallo!
Ich stelle hiermit meinen mathematischen Parser vor. Er dient dazu, komplexe mathematische Ausdrücke mit Klammern und Verschachtelungen wie z.B. "11*2(3-435+435)3435sin(43/(34-4))" berechnen zu können.
Der Parser unterstützt folgende Funktionen:
Weitere Funktionen kann ich gerne hinzufügen. Bitte daher um Feedback. So plane ich noch numerische Berechnungen von Differenzialquotienten und Integralen.
**Geeignet ab .NET Framework Version 2.0 SP1
Version: 1.0.1 **
Klassendiagramm
++Eigenschaften ++
System.String Expression
Der auszuwertende mathematische Ausdruck. Eventuelle Leerzeichen müssen vorher eliminiert
werden.
Quadsoft.TrigonometricMode Mode
Legt den Modus für die Rechnung mit Trigonometrischen Funktionen fest. (DEG = Gradmaß; RAD =
Bogenmaß)
System.Double XValue
Wert der Laufvariablen „x“, sofern sie im Ausdruck vorkommt.
Methoden
System.Double GetResult()
Gibt den berechneten Wert des mathematischen Ausdrucks zurück.
System.String GetResultAsString()
Wie GetResult(), aber als String.
Lizenz
Sie dürfen diese Bibliothek für Ihre (auch kommerziellen) Projekte unter der Bedingung der Namens
und Websitenennung des Herstellers verwenden, um die Funktionalität eines mathematischen Parsers
nutzen zu können. Dabei ist es untersagt, die Datei in eine andere einzukompilieren (Merging), sie zu
dekompilieren, oder sie ohne diese Lizenz zu vertreiben.
Beispiel für korrekte Namensnennung in den Credits:
Dieses Programm verwendet die Quadsoft.ExpressionParser Bibliothek von Adrian
Jablonski (http://www.quadsoft.org)
++Haftungsausschluss ++
Dieses Werk wird bereitgestellt "wie es ist", ohne jegliche Garantien, Haftungsansprüchen oder
sonstigen Bedingungen. Die Nutzung erfolgt auf dem alleinigen Risiko des Benutzers. Ferner kann der
Autor nicht die Fehlerfreiheit des Werkes, ja nicht einmal die korrekte Funktionalität gewährleisten.
Jeder, der dieses Werk verwendet, muss diese Bedingungen akzeptieren.
Programmierbeispiel
// Neue Instanz des Parsers erstellen
Quadsoft.ExpressionParser parser = new Quadsoft.ExpressionParser();
// Den Ausdruck festlegen
parser.Expression = "11*2(3-435+435)*3435*sin(43/34-4)";
// Modus für trigonometrische Funktionen
parser.Mode = Quadsoft.TrigonometricMode.Degrees;
// Ergebnis berechnen und anzeigen
Console.WriteLine(parser.GetResultAsString());
Console.ReadLine();
Mit freundlichen Grüßen
Adrian Jablonski
Es gibt hier im Forum ja doch schon einige andere Parser, hast du irgendwelche Vergleiche angestellt? Zum Beispiel was die Geschwindigkeit anbelangt?
Mfg
Aratar
Hallo Quadsoft,
Enthaltene Konstanten: e
Verträgt sich das mit der wissenschaftlichen Darstellung von Gleitkommazahlen? Oder wie können letztere eingegeben werden? Per E od. mit 10^?
mfG Gü
Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.
"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"
Nein, nein, e ist hier die eulersche Zahl. Die Exponentialschreibweise ist noch nicht implementiert, aber das wäre auch nur ein erstezen aller großen (!) E's durch "*10^".
Zur Performance:
Der Parser verwendet ausschließlich String-Operationen, keine regulären Ausdrücke. Momentan ist er etwa 25 % langsamer als der von Th69 und 30 mal schneller als der von zoomi (der ist ja auch rein RegEx). Getestet wurden mehrere Durchläufe eienr komplexen Formel mit einer Laufvariablen "x".
Hallo Quadsoft,
das Ersetzen mittels "*10^" solltest du auf keinen Fall tun, sondern wirklich den gesamten Literal-Ausdruck mittels Double.Parse() einlesen.
Und das dein Parser langsamer ist, wundert mich bei einem auf String-Operationen basierenden auch nicht (daher habe ich ja extra meinen Parser veröffentlicht, damit im Internet nicht immer wieder diese String/RegEx-(Frickel-)Parser veröffentlicht und benutzt werden - nur ein sauber auf EBNF basierender Parser läßt sich auch eindeutig verifizieren. Du schreibst ja in deiner Lizenz selber, daß du die korrekte Funktionalität nicht gewährleisten kannst).
Sofern es bei dir nur um eine Übung zum Schreiben eines Parsers ging, ist das aber in Ordnung so. 😉
Und an die Geschwindigkeit von meinem auf "Vorkompilierung" (Syntax-Baum) beruhenden Ansatz (z.B. zum Zeichnen eines Graphen, wo sich nur der x-Wert ändert), wirst du erst recht nicht so schnell herankommen.
Ich benutze zum Scannen aber kein RegEx, sondern nur den String, den ich per Indexer anspreche. Dann sind das nur noch String - und Char-Vergleiche. Es ist für mein Gefühl aber wirklich nicht langsam, immerhin sind es zu deiner zugegebenermaßen viel bessern methode nur 25 %. Bei einem einfachen TR würde man das nicht mal merken.
BTW zu dieser Lizenz: Das ist ein Standaradgelaber. Wenn das Programm wider erwarten abstützt, war das halt keine korrekte Funktionalität. Das heißt aber nicht, dass er nicht rechnen kann.