![]() |
Formel Parser
Hallo
ich suche einen Komponenten/eine Function, die mir aus einem String, meinetwegen 'x*2+36*sin(x)' und einem Wert für x die Gleichung ausrechnet. Also bei einem Wert von X=5 also 13,13... Das ganze sollte sehr schnell sein, da die Funktion ein Paar Hunderttausend mal aufgerufen wird. Mir würde auch eine DLL aus C++ zum Beilspiel reichen. Wenn die denn schneller ist! Auch Assembler-Code ist aktzeptabel, sofern er einfach zu bedienen ist! Danke TO |
Gut, ich habe einmal im Internet gesucht, habe auch nicht viel gefunden. Hier habe ich einen Code, der ziemlich gut funktioniert. Kann den sich mal jemand anschauen und feststellen, ob sich da noch etwas optimieren ließe?
Delphi-Quellcode:
[edit=Admin]Delphi-Tags eingefügt. Mfg. Daniel[/edit]
function pos0(const c:char;const s:string):integer;
var k,z:integer; //z:=Anzahl der Klammern begin z := 0; for k:=1 to length(s) do begin if s[k]='(' then begin inc(z); continue; end; if s[k]=')' then begin dec(z); continue; end; if (z=0) and (s[k]=c) then begin result:=k; exit; end; end; Result := 0; end; function copyab(const s:string; const i:integer):string; begin Result:=copy(s,i,length(s)-i+1) end; function pos0Ex(const c: Char; const s: string; out ResultValue: Integer): Integer; //pos0Ex findet das Zeichen "+","-" ... nicht innerhalb von Klammern var k, z: Integer; //z:=Anzahl der Klammern begin z := 0; for k := 1 to Length(s) do begin case s[k] of '(': Inc(z); ')': Dec(z); else if (z = 0) and (s[k] = c) then begin Result := k; //Treffer ResultValue := k; Exit; end; end; end; ResultValue := 0; Result := 0; end; function TermToReal(s:string):real; // {Bisher '+' '-' '*' '/' Klammern und 'x' integriert, // d.h. gebrochen rationale Funktionen werden ausgewertet var ps: Integer; begin //showmessage(s); Empfehlenswert zum Verständnis if pos0Ex('+',s,ps)>0 then result:=TermToReal(copy(s,1,ps-1))+TermToReal(copyab(s,ps+1)) else if pos0Ex('-',s,ps)>0 then result:=TermToReal(copy(s,1,ps-1))-TermToReal(copyab(s,ps+1)) else if pos0Ex('*',s,ps)>0 then result:=TermToReal(copy(s,1,ps-1))*TermToReal(copyab(s,ps+1)) else if pos0Ex('/',s,ps)>0 then result:=TermToReal(copy(s,1,ps-1))/TermToReal(copyab(s,ps+1)) else if pos0Ex('^',s,ps)>0 then result:=Power(TermToReal(copy(s,1,ps-1)),TermToReal(copyab(s,ps+1))) else if pos0Ex('$',s,ps)>0 then begin try result:=Power(TermToReal(copy(s,1,ps-1)),1/TermToReal(copyab(s,ps+1))); except Result := 0; end; end else if pos0Ex('s',s,ps)>0 then result:=sin(DegToRad(TermToReal(copyab(s,ps+1)))) else if pos0Ex('c',s,ps)>0 then result:=cos(DegToRad(TermToReal(copyab(s,ps+1)))) else if pos0Ex('t',s,ps)>0 then result:=tan(DegToRad(TermToReal(copyab(s,ps+1)))) else if (s<>'') and (s[1]='(') then begin //Am Anfang und Ende eine Klammer s:=copy(s,2,length(s)-2); result:=TermToReal(s) end else if s='x' then result:=x else //oder TermToReal(Form1.Ex.text) result:=StrToFloat(s); end; |
|
ja genau! Allerdings ist der Code immer noch relativ (!!!) langsam!
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 21:50 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