AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Problem mit Mathe-Parser

Ein Thema von athomas · begonnen am 30. Okt 2009 · letzter Beitrag vom 10. Nov 2009
Antwort Antwort
Seite 1 von 2  1 2      
athomas

Registriert seit: 4. Okt 2007
21 Beiträge
 
#1

Problem mit Mathe-Parser

  Alt 30. Okt 2009, 16:52
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;
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#2

Re: Problem mit Mathe-Parser

  Alt 30. Okt 2009, 17:10
Zitat:
arr:=s;
hier überschreibst du die vorher etstelle Instant der Stringliste!
richtiger wäre:
arr.Assign(s); PS: TStrings als Parameter macht sich besser (so kann man auch StringList-ähnliche Dinge übergeben
(z.B. Memo1.Lines , welches ich für meinen Test mal schnell genommen hab)


Zitat:
if i=1 then
das Minus ist ja wohl im Index 0
Zitat:
Delphi-Quellcode:
for j:=0 to arr.count-1 do
...
i:=i mod (arr.count);
setzt i auf 0 und führt die While-Schleite nochmals ab 0 aus
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
$2B or not $2B
  Mit Zitat antworten Zitat
athomas

Registriert seit: 4. Okt 2007
21 Beiträge
 
#3

Re: Problem mit Mathe-Parser

  Alt 30. Okt 2009, 17:32
danke schonmal für die schnelle antwort

ich hab deine tipps befolgt und die while-schleife von null gestartet:
Delphi-Quellcode:
//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;
negative vorzeichen funktionieren jetzt soweit ganz gut, aber wenn ich z.b. -1-2-3-4-5 eingebe, konnt -7 raus ^^
was stimmt denn noch nicht
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#4

Re: Problem mit Mathe-Parser

  Alt 30. Okt 2009, 17:42
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:
StringReplace(arr.Text, sLineBreak, ' | ', [rfReplaceAll])
und wenn es heißt "Funktion wurde vom Compiler entfernt", dann noch irgendwo im QuellText diese Funktion verwenden
z.B. einfach irgendwo StringReplace('','','',[]); einfügen (zwar voll sinnlos, aber nun ist diese Funktion vorhanden )

[add]
mach aus diesem
Delphi-Quellcode:
i:=i+1;
i:=i mod (arr.count);
einfach nur
i:=0; der Grund ist, daß so die Werte in der falschen Reihenfolge aufgelöst werden
-1-2-3-4-5 und dein Code macht ((-1)-2)-(3-4)-5
$2B or not $2B
  Mit Zitat antworten Zitat
athomas

Registriert seit: 4. Okt 2007
21 Beiträge
 
#5

Re: Problem mit Mathe-Parser

  Alt 30. Okt 2009, 18:17
wenn ich doch aber
Delphi-Quellcode:
i:=i+1;
i:=i mod (arr.count);
mit i:=0 ersetze komm ich in ne endlos-schleife, oder hab ich dich falsch verstanden?

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
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#6

Re: Problem mit Mathe-Parser

  Alt 30. Okt 2009, 18:31
Zitat von athomas:
ach ja, das problem mit -- oder +- hab ich einfach mit stringreplace lösen können
Was gar nicht nötig wäre, weil das kein korrekter mathematischer Ausdruck ist.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#7

Re: Problem mit Mathe-Parser

  Alt 30. Okt 2009, 18:33
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

Zitat von athomas:
ach ja, das problem mit -- oder +- hab ich einfach mit stringreplace lösen können
man hätte auch statt i=0 auf "ist davor nichts oder noch ein anderer Operator (+-*/)" bzw. "ist davor KEINE Zahl" prüfen können.
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?
$2B or not $2B
  Mit Zitat antworten Zitat
athomas

Registriert seit: 4. Okt 2007
21 Beiträge
 
#8

Re: Problem mit Mathe-Parser

  Alt 30. Okt 2009, 18:42
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:
//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;
wenn ich -2 * -2 rechne gibt er mir -2 aus, als ob er -* als einen unbekannten operator ansehen würde
  Mit Zitat antworten Zitat
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#9

Re: Problem mit Mathe-Parser

  Alt 30. Okt 2009, 18:46
Zitat von himitsu:
@NamenLozer:
1--2 aka 1 - -2 ist also nicht korrekt?
Ja. Bei so etwas sind Klammern nötig: Nur 1-(-2) ist formal korrekt.
  Mit Zitat antworten Zitat
athomas

Registriert seit: 4. Okt 2007
21 Beiträge
 
#10

Re: Problem mit Mathe-Parser

  Alt 30. Okt 2009, 18:54
war auch mein erster gedanke:
(-2)*(-2) kommt aber auch -2 raus
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 18:35 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz