Professioneller Taschenrechner

    • VB.NET

    Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von Nikx.

      Professioneller Taschenrechner

      Da ja hier das Taschenrechner-Schreiben 'zum guten Ton' gehört, hier ist meiner.

      Das Teil kann selbstverständlich Punkt vor Strich und negative Vorzeichen aber auch beliebige Klammerungen, Funktionen und Verschachtelungen.
      So einfache Sachen wie zB: ((sin(45)+3)*(5-7*log(4)))+cos(39-sqrt(5*4-16)) sind kein Problem.

      Zur Auswertung wird die eingegebene Formel zuerst rekursiv in einen binären Baum eingelesen und dieser anschließend mittels eines Inorderdurchlaufs berechnet.
      Die Hauptarbeit macht dabei die Funktion die den Baum erstellt, bereits dort werden die Prioritäten der einzelnen Ausdrücke berücksichtigt und dementsprechend im Baum abgelegt.
      Die Funktion die anschließend den Baum berechnet besteht im wesentlichen nur aus den rekursiven Aufrufen und einem großen Select Case-Block in dem die einzelnen Funktionen und Operatoren unterschieden werden.

      Zur Veranschaulichung habe ich noch eine Funktion eingebaut mit der man sich den Berechnungsbaum ansehen kann. Startknoten des Baumes ist der in der ersten Zeile, von dort aus wird dann gemäß Inorder 'zuerst nach links', 'dann der Knoten selbst', 'danach nach rechts' der Baum durchlaufen.
      Im Baum selbst sind keinerlei Klammern abgelegt, die entsprechende Bearbeitungsreihenfolge ergibt sich aus der Anordnung der Knoten. Wenn man sich die Abarbeitung anzeigen läßt, wird zur Verdeutlichung der Berechnungsreihenfolge jedoch die entsprechende Klammerung mit ausgegeben.


      Der Berechnungsalgorithmus (Baum erstellen und auswerten) incl den benötigten Funktionen und Klassen besteht aus ca 350 LOC (Lines Of Code), der Rest ist nur Beiwerk: Kommentare, Bedienung etc.
      Dateien
      • Rechner.zip

        (29,07 kB, 2.608 mal heruntergeladen, zuletzt: )
      Hi.
      Cool, danke für diesen nützlichen Code. Die Logik in diesem Code kann man auch gut für eigene Scriptsprachen verwenden, oder um Editoren und IDEs für Sprachen zu schreiben, da man somit die Funktionsklammern der Reihenfolge nach logisch abarbeiten kann.
      Werde das sicherlich mal irgendwann gebrauchen können ;)
      Weiter so 8o

      ~ Chris
      To make foobar2000 a real random music player, I figured out the only way to achieve this is to use Windows Media Player.

      At some point in time, you recognize that knowing more does not necessarily make you more happy.

      Chrisber schrieb:

      Hi.
      Die Logik in diesem Code kann man auch gut für eigene Scriptsprachen verwenden, oder um Editoren und IDEs für Sprachen zu schreiben, da man somit die Funktionsklammern der Reihenfolge nach logisch abarbeiten kann.
      Werde das sicherlich mal irgendwann gebrauchen können ;)

      Natürlich, auf diese oder ähnliche Art arbeiten ja auch die meißten Compiler und Interpreter soweit ich das vom Studium her noch richtig im Hinterkopf habe. :)
      Jo, genau das tun sie. Deshalb ist dein Code auch eine gute Vorlage um so etwas in der Art zu realisieren.
      Als Verbesserungsvorschlag würde ich noch einbauen, dass automatisch eine Klammer auf eingefügt wird, nachdem man z.B. auf Cos gedrückt hat - das erspart doch ein paar Klicks und rentiert sich schon bei einer kurzen Aufgabe.

      ~ Chris
      To make foobar2000 a real random music player, I figured out the only way to achieve this is to use Windows Media Player.

      At some point in time, you recognize that knowing more does not necessarily make you more happy.
      Natürlich könnte man automatisch die öffnende Klammer bei einer Funktion einfügen, aber dann müßte diese ja auch wieder geschlossen werden wozu man ja auch wieder einen Click braucht.

      Mein Rechner hat kein Problem damit wenn nach dem Funktionsnamen keine öffnende Klammer kommt, denn da kann auch einfach nur der Parameter durch ein Leerzeichen abgetrennt werden und das wird automatisch eingefügt wenn man mit den Buttons eingibt und keine öffnende Klammer davor ist.
      zB ist sin 45 und sin(45) für meinen Rechner das gleiche und sin 45+3 wird als sin(45)+3 interpretiert da dann, wenn der Parameter nur durch ein Leerzeichen getrennt ist, nur eine Zahl als Parameter genommen wird während natürlich sin(45+3) auch korrekt als sin(48) berechnet wird.
      Man muß aber nicht die Formel über die Buttons eingeben, man kann die auch einfach nur in das Textfeld tippen oder Buttons und Tippen kombinieren. Ebenso kann man da was über die Zwischenablage reinkopieren.
      Wenn man was eingibt das nicht berechenbar ist erhält man idR ein 'n. def.' (=nicht definiert) als Ergebnis.
      Übrigens: Leerzeichen kann man soviele zwischendrin einbauen wie man lustig ist...
      Hallo,
      ich weiß, dass dieses Thema bereits sehr alt ist, jedoch möchte ich einen kurzen Einwurf machen, da dies ja schließlich der Sourcecode-Austausch ist und es sicherlich Leute gibt, die diesen Code verwenden. (Außerdem habe ich gesehen, dass in diversen anderen neueren Threads auch hier her als "Musterlösung" verlinkt wurde).
      Ich rechne 4/2*3 und der Rechner gibt als Ergebnis: 0,666666666666667
      Mal und geteilt haben doch die gleiche Priorität, wenn keine Klammern gesetzt sind, weshalb man von links nach rechts rechnet, also: (4/2)*3
      (und der GTR bestätigt das natürlich auch)
      Ist ein solcher Code im Sourcecodeaustuasch dann überhaupt sinnvoll? Auch wenn er schon sehr alt ist, ist er eines der wenigen Beispiele für einen Taschenrechner hier im Forum.
      lg
      Suscurtl
      Was zum ...? Mit Punkt vor Strich ist doch nur gemeint, dass Division und Multiplikation vor Subtraktion und Addition durchzuführen sind.
      Und laut diversen Online-Quellen rechnet man bei gleicher Priorität der Operatoren von links nach rechts. (so wie ich es auch aus der Schule kenne O: )
      Erstaunlich, was den Leuten alles auffällt... nur dass Taste 9 nicht funktioniert wohl nicht...

      VB.NET-Quellcode

      1. Private Sub btnAlle_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) _
      2. Handles btn0.Click, btn1.Click, btn2.Click, btn3.Click, btn4.Click, btn5.Click, btn6.Click, _
      3. btn7.Click, btn8.Click, btnAbs.Click, btnACos.Click, btnASin.Click, btnATan.Click, _
      4. btnAuf.Click, btnCos.Click, btnCosH.Click, btnDurch.Click, btnE.Click, btnExp.Click, _
      5. btnHoch.Click, btnLn.Click, btnLog.Click, btnMal.Click, btnPi.Click, btnPlus.Click, _
      6. btnPunkt.Click, btnSin.Click, btnSinh.Click, btnSqrt.Click, btnTan.Click, btnTanH.Click, _
      7. btnZu.Click
      8. ...


      Gucki, kein Btn9 :)

      kinsi schrieb:

      * = punkt
      / = strich
      Da hast Du Dich aber sehr verirrt.
      Punkt-Rechnung: *, / (Multiplikation, Division)
      Strich-Rechnung: +, - (Addition, Subtraktion)
      @suscurtl: Sehr richtig. :thumbup:
      ---------------

      suscurtl schrieb:

      4/2*3
      ist einzig ein Problem der Klammersetzung, nicht aber Punkt- vor Strich-Rechnung.
      Mit der von links nach rechts-Regel steht da (4 / 2) * 3 = 6
      nicht aber
      4 / (2 * 3) = 0.666666666666666666.
      Für diese Interpretation sind die Klammern explizit zu setzen!
      ---------------
      Ansonsten empfehle ich die umgekehrte polnische Notation, da werden keine Klammern benötigt.
      Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
      Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
      Ein guter .NET-Snippetkonverter (der ist verfügbar).
      VB-Fragen über PN / Konversation werden ignoriert!
      Abend,

      sorry fürs ausgraben. Ich erarchte es allerdings für wichtig, anzumerken,
      dass der Taschenrechner leider nicht völlig korrekt arbeitet.

      (10/14)-3+(29/3)*17
      Taschenrechner: -166.62
      Google: 162.05

      Grüße
      "Life isn't about winning the race. Life is about finishing the race and how many people we can help finish the race." ~Marc Mero

      Nun bin ich also auch soweit: Keine VB-Fragen per PM! Es gibt hier ein Forum, verdammt!

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Nikx“ ()