![]() |
Problem mit Mathe-Parser
Hallo zusammen,
ich sitz hier vor nem kleinen problem mit einem formelparser. ich hab ne prozedur geschrieben, die einen klammerfreien ausdruck zerstückelt in zahlen und operatoren. eine weitere prozedur soll dieses array in ne gleitkommazahl umwandeln. klappt soweit auch ganz gut, nur wenn ich ein negatives vorzeichen hab bekomm ich den fehler, dass der index das maximum meiner tstringlist überschreiten würde. kann sich das bitte mal jemand ansehen :)
Delphi-Quellcode:
function arrBerechnen(s: TStringlist): real;
var i, j: integer; arr: TStringlist; ende: boolean; begin arr:=TStringlist.create(); arr.clear; arr:=s; //Produkt ende:=false; i:=1; if arr.count>1 then begin while not(ende) do begin if (arr[i]='*') then begin arr[i-1]:=floattostr(strtofloat(arr[i-1])*strtofloat(arr[i+1])); arr.delete(i); arr.delete(i); end; ende:=true; for j:=0 to arr.count-1 do if arr[j]='*' then ende:=false; i:=i+1; i:=i mod (arr.count); end; end; //Quotient ende:=false; i:=1; if arr.count>1 then begin while not(ende) do begin if (arr[i]='/') then begin arr[i-1]:=floattostr(strtofloat(arr[i-1])/strtofloat(arr[i+1])); arr.delete(i); arr.delete(i); end; ende:=true; for j:=0 to arr.count-1 do if arr[j]='/' then ende:=false; i:=i+1; i:=i mod (arr.count); end; end; //Differenz ende:=false; i:=1; if arr.count>1 then begin while not(ende) do begin if (arr[i]='-') then begin if i=1 then begin arr[i-1]:=floattostr(- strtofloat(arr[i])); arr.delete(i); end else begin arr[i-1]:=floattostr(strtofloat(arr[i-1])-strtofloat(arr[i+1])); arr.delete(i); arr.delete(i); end; end; ende:=true; for j:=0 to arr.count-1 do if (arr[j]='-')and(length(arr[j])=1) then ende:=false; i:=i+1; i:=i mod (arr.count); end; end; //Summe ende:=false; i:=1; if arr.count>1 then begin while not(ende) do begin if (arr[i]='+') then begin arr[i-1]:=floattostr(strtofloat(arr[i-1])+strtofloat(arr[i+1])); arr.delete(i); arr.delete(i); end; ende:=true; for j:=0 to arr.count-1 do if arr[j]='+' then ende:=false; i:=i+1; i:=i mod (arr.count); end; end; result:=strtofloat(arr[0]); arr.free; end; |
Re: Problem mit Mathe-Parser
Zitat:
richtiger wäre:
Delphi-Quellcode:
PS: TStrings als Parameter macht sich besser (so kann man auch StringList-ähnliche Dinge übergeben
arr.Assign(s);
(z.B. Memo1.Lines , welches ich für meinen Test mal schnell genommen hab) Zitat:
Zitat:
PS: fange gleich mit i:=0; an (bei + und -), dann muß da nicht doppelt bearbeitet werden PS: das + gibt es auch als Vorzeichen (hast du ganz vergessen) PSS: + und - als Vorzeichen innerhalb eines Strings "1+-2" dürfte auch Probleme bereiten |
Re: Problem mit Mathe-Parser
danke schonmal für die schnelle antwort
ich hab deine tipps befolgt und die while-schleife von null gestartet:
Delphi-Quellcode:
negative vorzeichen funktionieren jetzt soweit ganz gut, aber wenn ich z.b. -1-2-3-4-5 eingebe, konnt -7 raus ^^
//Differenz
ende:=false; i:=0; if arr.count>1 then begin while not(ende) do begin if (arr[i]='-') then begin if i=0 then begin arr[i]:=floattostr(- strtofloat(arr[i+1])); arr.delete(i+1); end else begin arr[i-1]:=floattostr(strtofloat(arr[i-1])-strtofloat(arr[i+1])); arr.delete(i); arr.delete(i); end; end; ende:=true; for j:=0 to arr.count-1 do if (arr[j]='-')and(length(arr[j])=1) then ende:=false; i:=i+1; i:=i mod (arr.count); end; end; was stimmt denn noch nicht |
Re: Problem mit Mathe-Parser
nimm mal arr.Text in die Liste der überwachten Ausdrücke (Strg+Alt+W) auf,
setze einen Haltepunkt (F5) vor diese Schleife und geh dann ab dort die Schleife mal im Einzelschritt (F7) durch in der Liste kannst du dann schrittweise beobachten, was mit deinem arr passiert PS: wenn arr.Text zu unübersichtlich ist, dann kann man auch dieses in diese Liste aufnehmen (Funktionsaufrufe natürlich gestatten)
Code:
und wenn es heißt "Funktion wurde vom Compiler entfernt", dann noch irgendwo im QuellText diese Funktion verwenden
StringReplace(arr.Text, sLineBreak, ' | ', [rfReplaceAll])
z.B. einfach irgendwo StringReplace('','','',[]); einfügen (zwar voll sinnlos, aber nun ist diese Funktion vorhanden :stupid: ) [add] mach aus diesem
Delphi-Quellcode:
einfach nur
i:=i+1;
i:=i mod (arr.count);
Delphi-Quellcode:
der Grund ist, daß so die Werte in der falschen Reihenfolge aufgelöst werden
i:=0;
-1-2-3-4-5 und dein Code macht ((-1)-2)-(3-4)-5 |
Re: Problem mit Mathe-Parser
wenn ich doch aber
Delphi-Quellcode:
mit i:=0 ersetze komm ich in ne endlos-schleife, oder hab ich dich falsch verstanden?
i:=i+1;
i:=i mod (arr.count); ach ja, das problem mit -- oder +- hab ich einfach mit stringreplace lösen können :) aber was mir noch aufgefallen ist: x*(-4) oder x/(-4) funktioniert auch nicht |
Re: Problem mit Mathe-Parser
Zitat:
|
Re: Problem mit Mathe-Parser
theoretisch nicht,
aber nachdem > - 1 - 2 - 3 - 4 - 5 bis hier aufgelöst wurde > -3 - 3 - 4 - 5 hier nach ist i nun 1 und es wird grad noch das - getroffen > -6 - 4 - 5 danach steht i durch deine Berechnung aber auf 2, verfehlt knapp das 1. "-" und nimmt sich als Nächstes erstmal das 2. "-" vor, also 4 - 5 > -6 - -1 und im letzten Durchgang kommt es dann natürlich zu > -7 stimmt ... die Endlosschleife hab ich glatt übersehn versuch mal nur i:=i+1; an dieser Stelle und wenn du was ersetzt hast, dann ma da gleich ein i:=i-1; oder i:=-1; rein :gruebel: Zitat:
denn wenn dieses zutrifft, dann handelt es sich bei diesem + oder - um ein Vorzeichen ... ansonsten um einen Operator @NamenLozer: 1--2 aka 1 - -2 ist also nicht korrekt? |
Re: Problem mit Mathe-Parser
stimmt ja, hab ich wohl übersehen: wenn ich die funktion delete aufrufe verschiebt sich ja das ganze array
also das addieren und subtrahieren funktioniert jetzt, aber ich hab jetzt ein problem beim multiplizieren mit negativen zahlen:
Delphi-Quellcode:
wenn ich -2 * -2 rechne gibt er mir -2 aus, als ob er -* als einen unbekannten operator ansehen würde
//Produkt
ende:=false; i:=1; if arr.count>1 then begin while not(ende) do begin if (arr[i]='*') then begin arr[i-1]:=floattostr(strtofloat(arr[i-1])*strtofloat(arr[i+1])); arr.delete(i); arr.delete(i); i:=i-2; end; ende:=true; for j:=0 to arr.count-1 do if arr[j]='*' then begin ende:=false; break; end; i:=i+1; end; end; |
Re: Problem mit Mathe-Parser
Zitat:
|
Re: Problem mit Mathe-Parser
war auch mein erster gedanke:
(-2)*(-2) kommt aber auch -2 raus |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:58 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz