Matheparser



  • Moin,

    Ich bin auf der suche nach einem Mathe-parser, der mathematische Funktionen (bsp: f(x) = x^43 + 24x) als String einlesen kann und mit dem ich dann das Ergebnis weiter verarbeiten kann ( zb wertetabellen der funktion erstellen).
    Das ganze sollte möglichst einfach sein. Ein tutorial wäre natürlich nicht schlecht 🙂 .
    Die Sprache sollte C oder C++ sein.

    Wäre nett, wenn mir jemand helfen könnte.
    Danke im vorraus !

    Lusches



  • Du musst zwangsläufig einen "Mini-Compiler" bauen.

    Du musst also erstmal eine Grammatik aufstellen die das nötigste kann:
    +, -, *, /, ^, (...), Punkt-Vor-Strich-Rechnung und dann evtl. noch Funktionen wie:
    sin, cos, sqrt, tan, etc.

    Dann musst du nur noch Variablen einfügen.

    Und dann hast dus geschafft.

    Ein Tutorial, welches genau das macht, was du willst wirst du sicher nicht finden. Du musst also aus VIELEN Tutorials und evtl. auch Büchern alles zusammenbauen, wie ein Puzzle.

    Aber ich schätze diese Aufgabe ist für dich noch nicht lösbar.

    Viel Spaß 😃



  • Da gibt es mehrere Möglichkeiten. z.B. die Infix-Notation in einen Baum transformieren und dann durchwandern oder die Infix-Notation in eine Präfix/Postfix-Notation umwandeln und dann mittels Stack ausrechnen.



  • Hi, danke erstmal für die hilfe.

    Basic ist eine Interpretersprache und müsste sowas ja normalerweise können. Dann muss es ja möglich sein, einfach den quelltext von basic nach c++ umzuschreiben.
    Weiß jemand, wo ich den quelltext von den Basic-funktionen finden kann ?

    Danke
    Lusches



  • Was hast du denn jetzt vor???

    Also hier hast du den Code für einen simplen Taschenrechner, er kann eben nur die 4 Grundrechenarten:

    #include <stdio.h>
    #include <stdlib.h>
    #include <conio.h>
    
    #define ADD 0
    #define SUB 1
    #define MUL 2
    #define DIV 3
    
    int digit(const char c) 
    {
        if(c <= '9' && c >= '0')
            return 1;
    
        return 0;
    }
    
    int parse(const char *str)
    {
        int                   erg = 0;
        const char          *_s = str;
        int                  op = ADD;         
    
        int buffer = 0;
    
        while(*_s) 
        {
            // Leerzeichen überlesen
            while(*_s == ' ')
                _s++;
    
            // Für Zahlen >= 10
            while(digit(*_s)) 
            {
                buffer = 10 * buffer + (*_s -  0x30); // 0x30 = '0' siehe Ascii Tabelle
                _s++;
            }
    
            switch(op) 
            {
                case ADD:
                    erg = erg + buffer;
                    break;
                case SUB:
                    erg = erg - buffer;
                    break;
                case MUL:
                    erg = erg * buffer;
                    break;
                case DIV:
                    if(buffer == 0)
                        erg = 0;
                    else
                        erg = erg / buffer;
                    break;
                default:
                    _s++;
                    break;
            }
    
            // Leerzeichen überlesen
            while(*_s == ' ')
                _s++;
    
            switch(*_s) 
            {
                case '+':
                    op = ADD;
                    break;
                case '-':
                    op = SUB;
                    break;
                case '*':
                    op = MUL;
                    break;
                case '/':
                    op = DIV;
                    break;
                default:
                    op = -1;
                    break;
            }
    
            buffer = 0;
            _s++;
        }
    
        return erg;
    }
    
    int main(int argc, char *argv[])
    {
        char cinput[100];
    
        while(cinput[0] != 'q')
        {
            printf("Eingabe: ");
            gets(cinput);
    
            printf("\n\t %s = %i\n\n", cinput, parse(cinput));
        }
    
        getch();
    }
    

    Solltest du schon diesen Code nicht verstehen, bezweifel ich das du es schaffen wirst dein Vorhaben zu realisieren. Das einzige was du machen könntest, wäre eine Lib zu suchen die für dich rechnet. Oder du findest einen Befehl eval() und gehst einfach über deinen String und ersetzt x durch eine Zahl etc...
    => Du kannst dann aber nicht mehr 24x schrieben sondern musst 24*x schreiben!

    Es gibt verschiedene Möglichkeiten, es selbst zu schreiben wäre wohl die schwierigste aber auch die flexibelste.

    Jedenfalls ist das Thema leider nicht ganz ohne 🙄

    Viele Grüße,
    Blabbbb



  • gibt ja auch schon fertige libs dafür. muparser ist bspw. eine davon.



  • wir verwenden auch seit Jahren den muParser!
    Nur zu empfehlen und in kontinuierlicher Entwicklung. Das Ding ist von Ingo Berg und hier zu finden.
    Alternativ sei ebenfall snoch der ebenfalls kostenlose MtParser, der hier zu finden ist, erwähnt



  • Wie wärs mit GiNaC? siehe hier: http://www.ginac.de/
    Habs schon mit Erfolg ausprobiert, modern, C++ und ziemlich intuitiv verständlich. Diese Bibliothek nutzt Operatorüberladung ziemlich ausgiebig und der Code ist daher auch schön zu lesen (außer für die Gegner von Operatorüberladung 😉 ). Eine Wertetabelle wäre mithilfe einer Schleife, GiNaCs Substitutions- und Berechnungsfunktion innerhalb von wenigen Zeilen generiert.


Log in to reply