While-Schleife Endet zu früh



  • Wenn ich keinen String als Term benutzten soll, stellt sich die Frage wie ich Beispielsweise "sin(3*(2+4*4))" berechnen kann.

    Mein aktueller Ansatz übergibt meiner Klasse Mathlogic den Term als String
    dieser sucht nach der innersten klammer "(2+43)".
    Anschließend wird darin nach dem Rechenzeichen mit der höheren Priorität gesucht in diesem Fall "
    ".
    Nun werden die Zahlen vor und nach dem Rechenzeichen gesucht "4" und "3",
    welche ich dann in double umwandele und berechnen lasse.
    Das Ergebnis setzte ich dann ein "(2+12)" usw... (14) klammer löschen ...sin(3*14) ... sin(42) ... 0.6691306063

    Meine Klass Mathlogic macht das wie ich finde auch völlig Zufriedenstellend
    nur kommt sie auf eine eingabe wie 1.999E-05*3 nicht klar.
    Höchstwahrscheinlich könnte ich das ganze auch noch abfangen
    aber ob ich dies nun in der Klasse tue oder schon vor dem Aufruf dafür sorge,
    dass sowas nicht vorhanden ist macht für mich keinen Unterschied.



  • Gobbles schrieb:

    Wenn ich keinen String als Term benutzten soll, stellt sich die Frage wie ich Beispielsweise "sin(3*(2+4*4))" berechnen kann.

    Ganz einfach: Du parst den Inputstring, baust einen Baum und arbeitest diesen ab.



  • Sollte das Sarkasmus sein gehen wir nun besser zurück zu Produktivem, falls nicht hab ich keine Ahnung von was du da redest



  • Das war kein Sarkasmus.
    Du kannst deinen Ausdruck mit einem Algorithmus wie z.B. dem Shunting-yard algorithm parsen.
    Ist zwar keine einfache, dafür aber eine sehr elegante Lösung. Dann musst du nicht mehr mit strings rumhantieren und dein Problem ist auch gelöst. 😉



  • Hab mir das nun mal angeschaut Ansich auch interessant nur finde ich das kaum Eleganter gelöst.
    Da auch hier genauso viel beim Auslesen beachtet werden muss in welcher Reihenfolge was abgearbeitet wird
    und auch hier müsste ich es bei dem Einlesen abfangen das bei einer Zahl wie 1.99E-05 beispielsweise das - nicht als Operator
    sondern zu der Zahl an sich gehört. Kurz gesagt ich lande beim Selben Problem,
    welches ich nun aber schon Zufriedenstellend gelöst hab durch das toString konvertieren mit dem Parameter "Fxx"



  • Gobbles schrieb:

    [...]nur finde ich das kaum Eleganter gelöst.

    Woher stammt nur diese Obsession von Anfängern mit Eleganz? Versteh erstmal die Grundlagen und dann, wenn das Grundwissen sitzt und Du anfängst tatsächlich zu verstehen worum es geht, dann darfst Du anfangen über Eleganz zu reden. If anything, dann ist Eleganz eine Folge von guten Lösungsansätzen...

    Gobbles schrieb:

    [...]welches ich nun aber schon Zufriedenstellend gelöst hab

    Ich sage nur: http://de.wikipedia.org/wiki/Dunning-Kruger-Effekt

    Lies den Artikel und versteh was es mit Dir zu tuen hat.

    Und nein, wenn Du INTERN einen Zahlenwert erst in einen String verwandeln mußt um ihn dann wieder in einen Zahlenwert zu parsen dann ist das mit an Sicherheit grenzender Wahrscheinlichkeit ein mieses Design. Ebenso wenn Du eine while-Schleife benutzt um eine for-Schleife zu simulieren, dann ist auch das ein schlechtes Zeichen. Dein Code stinkt im Sinne von: http://en.wikipedia.org/wiki/Code_smell



  • Gobbles: Nimm einfach meinen Parser für mathematische Formeln 😉

    Dort ist auch ein Graph-Programm (inkl. Source-Code) in einem der unteren Beiträge als Anhang.



  • loks sollte man wohl besser ignorieren, zum einen weil ich mir nicht anhören muss das ich mein können unterschätze ohne mich überhaupt zu kennen und zweitens warum sollte man zwingend eine For-schleife nehmen obwohl eine While-schleife ca 5-7% schneller ist? In sofern spar dir Sinnlose Kommentare.

    Th69 schrieb:

    Gobbles: Nimm einfach meinen Parser für mathematische Formeln 😉

    Danke für das Angebot, aber ich würde das gerne eigenständig machen.
    Durch Copy-Paste ist die Lernkurve nicht so groß 😉



  • Gobbles schrieb:

    loks sollte man wohl besser ignorieren, zum einen weil ich mir nicht anhören muss das ich mein können untüberschätze ohne mich überhaupt zu kennen [...]

    ftfy. Und loks hat schon Recht ...

    Gobbles schrieb:

    [...] und zweitens warum sollte man zwingend eine For-schleife nehmen obwohl eine While-schleife ca 5-7% schneller ist? [...]

    R O F L M A O !



  • Gobbles schrieb:

    eine While-schleife ca 5-7% schneller ist?

    Da bin ich aber auf eine Erklärung gespannt 😃



  • Gobbles schrieb:

    loks sollte man wohl besser ignorieren, zum einen weil ich mir nicht anhören muss das ich mein können unterschätze ohne mich überhaupt zu kennen

    Das hat loks auch gar nicht ausdrücken wollen, sondern eher das Gegenteil dessen.

    Gobbles schrieb:

    und zweitens warum sollte man zwingend eine For-schleife nehmen obwohl eine While-schleife ca 5-7% schneller ist? In sofern spar dir Sinnlose Kommentare.

    Schwupps, nur haste keine Fachleute mehr im Thread. Die helfen zwar gern, aber man kennt auch die Grenzen.

    Gobbles schrieb:

    Durch Copy-Paste ist die Lernkurve nicht so groß 😉

    Aber auch nicht, indem man das Infinite-Monkey-Theorem zur Grundlage des Wissenserwerbs macht.



  • Hatte das vor einiger Zeit mal gestestet

    private void Button_Click_1(object sender, RoutedEventArgs e)
            {
                DateTime dtstart = DateTime.Now;
                int iMax = 200000000;
                int check = 0;
                for (int i = 0; i < iMax; i++)
                {
                    check++;
                }
                DateTime dtende = DateTime.Now;
                TimeSpan tszeit = dtende - dtstart;
                LBAusgabe.Items.Add("For-Schleife : " + tszeit.Seconds.ToString() + "." + tszeit.Milliseconds.ToString() + "sec");
            }
    
            private void Button_Click(object sender, RoutedEventArgs e)
            {
                DateTime dtstart = DateTime.Now;
                int iMax = 200000000;
                int check = 0;
                int i = 0;
                while (i < iMax)
                {
                    check++;
                    i++;
                }
                DateTime dtende = DateTime.Now;
                TimeSpan tszeit = dtende - dtstart;
                LBAusgabe.Items.Add("While-Schleife : " + tszeit.Seconds.ToString() + "." + tszeit.Milliseconds.ToString() + "sec");
            }
    

    habs eben nochmal laufen lassen und folgende Ergebnise bekommen

    For Schleife in (sec)
    0.149
    0.143
    0.145
    0.145
    0.163
    0.154
    ~ 0.14983333

    While Schleife in (sec)
    0.145
    0.152
    0.150
    0.143
    0.145
    0.151
    ~ 0.14766666



  • volkard schrieb:

    Schwupps, nur haste keine Fachleute mehr im Thread. Die helfen zwar gern, aber man

    vielleicht auch besser Anfangs wurden ja noch interessante Aussagen getätigt die auch zur Problemlösung beitragen wollten.
    Aber mittlerweile wird man ja nur noch angegangen weils für einige hier wohl nicht der sauberste weg ist darauf kann ich gern verzichten...
    Ich bin zufrieden so wie es ist und nachdem das Problem der E-Formen nun auch gelöst ist finde ich momentan keinen weiteren Fehler in meinem Rechner,
    egal welchen Term ich Eingebe bekomme ich ein Ergebnis welches bis auf 15-Nachkommastellen genau ist.
    Selbst Funktionen wie sin(1/x) die nahe X=0 recht wild werden bekommt er mindestens genau so gut hin wenn nicht sogar noch besser als mein grafischer Casio Taschenrechner.

    In sofern bedanke ich mich bei all dennen die sich bemüht haben mir zu helfen

    cya


  • Administrator

    Gobbles schrieb:

    habs eben nochmal laufen lassen und folgende Ergebnise bekommen

    For Schleife in (sec)
    0.149
    0.143
    0.145
    0.145
    0.163
    0.154
    ~ 0.14983333

    While Schleife in (sec)
    0.145
    0.152
    0.150
    0.143
    0.145
    0.151
    ~ 0.14766666

    *hust*
    http://msdn.microsoft.com/en-us/library/system.datetime.now.aspx

    System                   | Approximate Resolution
    -------------------------+-------------------------------
    Windows NT 3.5 and later | 10 milliseconds
    Windows 98               | 55 milliseconds
    

    The Now property is frequently used to measure performance. However, because of its low resolution, it is not suitable for use as a benchmarking tool.

    Du misst Mist.

    Die Leute wollten dir hier anfangs noch helfen, aber du lieferst hier ein Paradebeispiel des Dunning-Kruger-Effekts.

    Es wäre aber ehrlich gesagt durchaus noch interessant zu sehen, wie denn deine MathLogic Klasse aussieht. Hier wollen dir sehr kompetente Leute helfen, damit du dich verbessern kannst. Die haben zum Teil langjährige Erfahrungen und haben schon deutlich komplexere Probleme gelöst. Du hast somit zwei Optionen. Komm von deinem hohen Ross herunter und lern dabei etwas. Oder ignoriere die Leute und mach dich dabei mit solchen seltsamen Aussagen noch lächerlich. Ich empfehle dir die erstere Option. Damit kommst du weiter.



  • warum ich wegen dem DataTime.Now misst Messe kann ich gerade nicht ganz nachvollziehen,
    da ich es für beide gleichermaßen Nutze sollte die Ungenauigkeit keine Rolle spielen. Falls ich mich darin irren sollte so klär mich auf 😉

    Ich finde das hat weniger was mit einem hohen Ross als eher damit zu tun "wie man in den wald hineinruft so schallt es heraus" aber gut *absitz*

    hier hast du meine Klasse

    https://www.dropbox.com/s/nmgpipp2rphylrp/Mathlogic.cs



  • Gobbles schrieb:

    warum ich wegen dem DataTime.Now misst Messe kann ich gerade nicht ganz nachvollziehen, [...]

    Du misst 149±10 und 147±10 ... sag' mir jetzt doch bitte nochmal, was schneller ist ...

    Gobbles schrieb:

    hier hast du meine Klasse

    // ...
    
                if (offeneKlammern == geschlosseneKlammern)
                {
                    if (offeneKlammern > 0 && geschlosseneKlammern > 0)
                    {
                        return offeneKlammern;
                    }
                    else
                    {
                        return 0;
                    }
                }
                return -1;
    

    Ohne Worte.



  • was ist eigentlich dein Problem? wäre ich Profi müsste ich hier nicht nach Hilfe fragen wenn du was dazu beitragen willst dann tu es Vernünftig.




  • Administrator

    Gobbles schrieb:

    Ich finde das hat weniger was mit einem hohen Ross als eher damit zu tun "wie man in den wald hineinruft so schallt es heraus" aber gut *absitz*

    So kann man es auch bezeichnen. Aber das kann man auch auf dich beziehen. Und so eskaliert es sich dann bekanntermasen gegenseitig nach oben.

    Gobbles schrieb:

    was ist eigentlich dein Problem? wäre ich Profi müsste ich hier nicht nach Hilfe fragen wenn du was dazu beitragen willst dann tu es Vernünftig.

    Bezüglich der Zeitmessung:
    Die Auflösung ist viel zu ungenau. Du hast einen Unterschied, welcher unterhalb der Auflösung ist. Grundsätzlich musst du hier zwei Intervalle miteinander vergleichen: 0.139 - 0.159 und 0.137 - 0.157. Der Wert kann jeweils irgendwo in diesem Intervall liegen. Korrekt wäre also zum Beispiel 0.139 und 0.157 oder 0.159 und 0.137, etc. Es kann somit keine Aussage darüber gemacht werden, was tatsächlich schneller ist. Zudem hast du auch viel zu wenig Messungen durchgeführt und das auch noch mit den falschen Mitteln.

    Performanceüberlegungen, erst recht in diesem Minibereich, sollte man am besten sein lassen, wenn man nicht ganz genau weiss, was man tut. Optimierungen auf dieser Ebene haben in C# keinen Sinn. Wenn du optimieren willst bezüglich der Geschwindigkeit, dann wäre es vielleicht eher interessant, die MathLogic Klasse an sich zu optimieren. Nämlich wie sie überhaupt funktioniert und ob die Lösung effizient ist. Aber dazu benötigt man meistens entsprechende Tools, wie z.B. dotTrace von JetBrains. Nur sehr grobe Optimierungen machen überhaupt Sinn, ohne entsprechende Tools oder mit der Stopwatch Klasse zu tätigen. Sonst misst du allenfalls auch Seiteneffekte mit, Live-Optimierungen der CPU oder der Runtime, etc. etc.

    Richtige Performancemessung ist ein recht komplexes und umfangreiches Thema. Als Anfänger verbrennt man sich hier nur die Finger.

    Bezüglich dem "ohne Worte" von Swordfish:
    Können offeneKlammern oder geschlosseneKlammern überhaupt jemals kleiner wie 0 sein? Benötigt es die innere If-Abfrage überhaupt?

    Da ich gerade nicht viel Zeit habe und mir den Code nicht genauer angeschaut habe, nur eine positive Anmerkung:
    Du hast die Funktionen kommentiert! Das ist sehr toll zu sehen. Wenn du hier nun noch entweder die C# XML Comments nehmen würdes oder z.B. die Syntax von Doxygen, dann wäre das noch ein grösseres Plus. Denn daraus lassen sich automatisch Dokumentationen zum Code generieren.



  • Dravere schrieb:

    Bezüglich dem "ohne Worte" von hustbaer:

    Det war nischt isch.


Anmelden zum Antworten