While-Schleife Endet zu früh



  • Gobbles schrieb:

    Durch die Umwandlung ins E-Format hat ist ein Fehler in der Berechnung ergeben und der Code wurde Vorzeitig jedoch ohne Fehler beendet.

    Nein. Da ist nirgends eine Umwandlung ergo auch kein Fehler der dazu führt dass die Schleife zu früh abbricht.



  • Die Schleifenbedingung hängt nur von i und xMax ab, also solltest du uns alles zeigen, was damit zu tun hat. Die irrelevanten Teil darfst du dagegen gerne weglassen.



  • Natürlich entstand eine Umwandlung in das E-Format und zwar wenn i lim -> 0 kam es irgendwann dazu das i = 1.99E-05 wurde.
    dabei wurde der Term x^2 zu 1.99E-05 da meine Klasse Mathlogic aber damit nichts anfangen konnte lief was falsch.
    Warum diese aber keinen Error dabei ausgegeben hat wundert mich da wenn ich 1.99E-05^2 per Hand berechnen lasse
    es mir einen Fehler meldet das ich 1.99E nicht in double Umwandeln kann was ja auch logisch erscheint

    das ändern von
    VarX = i.ToString();
    zu
    VarX = i.ToString("F10");
    hat das Problem beseitigt da nun kein E-Format in dem Term-String landet

    PS: Alles was mit der Schleife und deren Bedinungen verknüpft ist ist bereits in dem Code enthalten das Problem lag an meiner Klasse Mathlogic diese zu Posten würde aber glaube jeglichen Rahmen sprengen -.-



  • Deine Erklärung ergibt irgendwie keinen Sinn, aber gut, wenns geholfen hat :p

    Gobbles schrieb:

    PS: Alles was mit der Schleife und deren Bedinungen verknüpft ist ist bereits in dem Code enthalten

    Nein, man kann aus dem Code nicht Wert und Typ von xMax ablesen, auch von xMin und increse [sic] nicht. Das Inkrement hast du bei der zweiten Variante, die angeblich vollständiger sein sollte, sogar weggelöscht.



  • Siehe ersten Beitrag 🙂

    increase = 0.0182149
    xMin = -10
    xMax = 10

    oh ja das fehlt natürlich so sollte es eigentlich aussehen 🙂

    increse = Math.Round((xMax - xMin) / width, 7); 
    myPoints = new Point[4, (int)((xMax - xMin) / increse)+1]; 
    
    double i = xMin; 
    int j = 0; 
    string VarX = ""; 
         while (i <= xMax) //tbRangeEnd 
         { 
             if (Funk1 != "") 
             { 
                  i = Math.Round(i, 7);; 
                  VarX = i.ToString("F10"); 
                  string Term = Funk1; 
                  Mathlogic myMath = new Mathlogic(Term.Replace("X", VarX)); 
                  myPoints[0, j].Y = dblY_X -Math.Round(Convert.ToDouble(myMath.getErgebnis()), 15) * dblPitchPixelY / pitch); 
                  myPoints[0, j].X = dblX_Y + Math.Round(i,15)*dblPitchPixelX/pitch; 
    
              } 
              j++;
              i += increse; 
         }
         if (Funk1 != "") 
         { 
              drawPoints(0); 
          } 
    }
    


  • jetzt fehlt immernoch der typ, auch wenn das wohl 3 mal double sein wird



  • KN4CK3R schrieb:

    jetzt fehlt immernoch der typ, auch wenn das wohl 3 mal double sein wird

    ja alle 3 in double auch mit decimal schon getestet mit gleichem Problem aber wie gesagt mit der toString("F20") funktioniert es nun Tadellos



  • richtig lösen würdest du dein problem wahrscheinlich wenn du einen int für die schleife nehmen würdest und den double wert dann jedes mal berechnest



  • KN4CK3R schrieb:

    richtig lösen würdest du dein problem wahrscheinlich wenn du einen int für die schleife nehmen würdest und den double wert dann jedes mal berechnest

    Und falsch lösen indem du den Code verwendest den du hier gepostet hast. 🤡
    An double liegt das nicht, so schlimm sind die Rundungsfehler nun auch wieder nicht.

    Gehen wirs mal anders an: Wie kommst du denn darauf dass die Schleife nicht oft genug ausgführt wird ?
    Kann das nchct auch ein Problem in der Zeichenlogik sein - oder hast du das wirklich nachgeprüft ?



  • Danke für die idee ich werde es gleich mal versuchen.
    Der Schleifenabbruch entstand wie schon erwähnt jedoch durch die Übergabe eines Termes an meine Mathlogic der ein E-Format beinhaltet, das Seltsame dran war nur das er mir keinen Fehler ausgegeben hat, was eigentlich passieren sollte. Zumindest tut es dies, wenn ich nur einen Wert mit einem E-Format berechnen lasse



  • So Funktion wurde umgeschrieben jedoch mit dem selben Problem.
    Bei einem Test hatte ich das selbe Problem das ich ab einem Bestimmten Punkt nahe 0 ein E-Format erhatlen habe.
    Die Ausgabe der Messagebox war:

    VarX = -1.989999999998506E-05 j = 549 increse = 0.0182149

    xMax = 10.0 (double)
    xMin = -10.0 (double)
    width = 1098 (double)

    double increse = Math.Round((xMax - xMin) / width, 7); 
    Points[,] myPoints = new Point[4, (int)((xMax - xMin) / increse)+1];
    int j = 0;
    string VarX;
    
    while(j < myPoints.Length/4)
       {
       // i = Math.Round(i, 7); ;
       // VarX = i.ToString("F20");
       VarX = (xMin + (j * increse)).ToString();
       if (VarX.Contains('E'))
          {
             MessageBox.Show("VarX = " + VarX + " j = " + j.ToString() + " increse = " +increse.ToString());
          }
          j++;
       }
    


  • E Format (aka scientific notation) vermeidet man z.B. mit Formatstrings:

    number.ToString("F9"); //9 decimals fixedpoint
    

    Wobei das gar nicht das Problem ist, das eigentliche Problem ist dein Design. Ein Taschenrechner sollte NIE einen string zum Rechnen brauchen!
    Ausgabe ist ok, aber nicht zur Berechnung deines Terms.
    Und bei der Ausgabe kannst du die wissenschaftliche Notation verwenden, oder eine Lösung von Stackoverflow: Double to string conversion without scientific notation nutzen.



  • 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ß 😉


Anmelden zum Antworten