PROBLEM BEI EINEM MATHE-FUNKTIONSPLOTTER
-
gute abend,
ich bin noch recht unerfahren in C++ und habe heute mein erstes programm fertiggestellt: einen funktionsplottet der mathematische funktionen(2D) plottet.
bis jetzt hat es auch für den anfang sehr gut geklappt und mein programm wäre fertig, wenn da nicht folgendes problem wäre:
MAN KANN KEINEN EIGENEN FUNKTIONSTERM EINGEBEN!!!
das bedeutet, dass der funktionsterm im quelltext eingegeben werden muss und das programm dadurch fast keinen nutzen hat.
im quelltext wird der term wie folgt eingegeben:float f(float x) { float f=sin(x*x); //EINGABE DES FUNKTIONSTERMS return f; }das funktioniert natürlich auch, aber es wäre sehr viel nützlicher, wenn man in einem EditFeld einen funktionsterm eingeben könnte und dieser dann von programm verwendet würde.
hat vielleicht jemand eine idee oder einen quelltext, der dieses problem lösen kann; ich würde das programm nämlich sehr gerne zusammen mit meiner facharbeit abgeben (oberstufe).
schon einmal VIELEN LIEBEN DANK
gruß,
dominik
-
-
danke für diesen verweis, ich habe darunter auch einen unübersehbaren link gefunden (http://swem.de/parser.htm). das ist GENAU das, was ich suche und brauche.
allerdings ist die erklärung (*.pdf-format; ist in der datei "fxypc.zip" enthalten) ein böhmisches dorf für mich. ich habe versucht mit dieser erklärung die beiden dateien ("Fnkt.h" & "Fxypc.cpp") selbstständig einzubinden, allerding ohne jeglichen erfolg.
kann mir jemand sagen, wie ich diese dateien in meine funktion einbinden muss (siehe meinen ersten post), so dass der funktionsterm in ein Edit-Fenster eingegeben werden kann und der wert f(x) für ein gegebenes x zurückgegeben wird???vielen dank und ein schönes restwochenende!
gruß,
dominik
-
DER CODE - MEIN PROBLEM
://--------------------------------------------------------------------------- #include <vcl.h> #pragma hdrstop #include "Unit1.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- #include<stdio.h> #include<string.h> #include"fnkt.h" UserFunction::UserFunction() { is_definded=FALSE; def_size=0; fcode=scode=NULL; fkonst=skonst=NULL; } UserFunction::~UserFunction() { if(fcode) { delete[] fcode; } if(scode) { delete[] scode; } if(fkonst) { delete[] fkonst; } if(skonst) { delete[] skonst; } } UINT UserFunction::f_def(char *inbuf) { is_definded=FALSE; def_size=strlen(inbuf); if(fcode) delete[] fcode; fcode=new DWORD[def_size+50]; if(!fcode) return(NO_MEM); if(scode) delete[] scode; scode=new DWORD[def_size+50]; if(!scode) return(NO_MEM); if(fkonst) delete[] fkonst; fkonst=new long double[def_size+50]; if(!fkonst) return(NO_MEM); if(skonst) delete[] skonst; skonst=new long double[def_size+10]; if(!skonst) return(NO_MEM); if(fwandel(inbuf)) return(SYNTAX_ERROR); is_definded=TRUE; return(TRUE); } long double UserFunction::calc(long double x, long double y) { DWORD klamv,kanf,kend,z; DWORD vs; konstind=skonstind; codeind=scodeind; klamanz=sklamanz; for(z=0; z < codeind; ++z) fcode[z]=scode[z]; for(z=0; z < konstind; ++z) fkonst[z]=skonst[z]; pritrans=spritrans; prihoch=sprihoch; primul=sprimul; priadd=spriadd; while( klamanz > 0 ) { klamv=kanf=kend=0; while( klamv != klamanz ) { if( fcode[kanf] == fklamauf ) { ++klamv; } ++kanf; } kend=kanf; while( fcode[kend] != fklamzu ) ++kend; vs=rechnen(kanf,kend,x,y); fcode[kanf-1]=nop; fcode[kend-vs]=nop; ordnen(); --klamanz; } rechnen(0,codeind,x,y); if( fcode[0] == fcx ) return(x); else if( fcode[0] == fcy ) return(y); else return(fkonst[fcode[0]]); } DWORD UserFunction::rechnen(DWORD ranf,DWORD rend,long double x,long double y) { DWORD l,vs; long double a,b; vs=0; if( pritrans > 0 ) { l=ranf; while( l < rend ) { switch(fcode[l]) { case fsin: if( fcode[l+1]==fcx ) a=x; else if( fcode[l+1]==fcy ) a=y; else a=fkonst[fcode[l+1]]; fkonst[konstind]=sin(a); fcode[l]=konstind; ++konstind; fcode[l+1]=nop; ++vs; --pritrans; l += 2; ordnen(); --rend; break; case fcos: if( fcode[l+1]==fcx ) a=x; else if( fcode[l+1]==fcy ) a=y; else a=fkonst[fcode[l+1]]; fkonst[konstind]=cos(a); fcode[l]=konstind; ++konstind; fcode[l+1]=nop; ++vs; --pritrans; l += 2; ordnen(); --rend; break; case ftan: if( fcode[l+1]==fcx ) a=x; else if( fcode[l+1]==fcy ) a=y; else a=fkonst[fcode[l+1]]; fkonst[konstind]=tan(a); fcode[l]=konstind; ++konstind; fcode[l+1]=nop; ++vs; --pritrans; l += 2; ordnen(); --rend; break; case fexp: if( fcode[l+1]==fcx ) a=x; else if( fcode[l+1]==fcy ) a=y; else a=fkonst[fcode[l+1]]; fkonst[konstind]=exp(a); fcode[l]=konstind; ++konstind; fcode[l+1]=nop; ++vs; --pritrans; l += 2; ordnen(); --rend; break; case fln: if( fcode[l+1]==fcx ) a=x; else if( fcode[l+1]==fcy ) a=y; else a=fkonst[fcode[l+1]]; if(a <= 0.0) a=1e-10; fkonst[konstind]=log(a); fcode[l]=konstind; ++konstind; fcode[l+1]=nop; ++vs; --pritrans; l += 2; ordnen(); --rend; break; case fsinh: if( fcode[l+1]==fcx ) a=x; else if( fcode[l+1]==fcy ) a=y; else a=fkonst[fcode[l+1]]; fkonst[konstind]=sinh(a); fcode[l]=konstind; ++konstind; fcode[l+1]=nop; ++vs; --pritrans; l += 2; ordnen(); --rend; break; case fcosh: if( fcode[l+1]==fcx ) a=x; else if( fcode[l+1]==fcy ) a=y; else a=fkonst[fcode[l+1]]; fkonst[konstind]=cosh(a); fcode[l]=konstind; ++konstind; fcode[l+1]=nop; ++vs; --pritrans; l += 2; ordnen(); --rend; break; case ftanh: if( fcode[l+1]==fcx ) a=x; else if( fcode[l+1]==fcy ) a=y; else a=fkonst[fcode[l+1]]; fkonst[konstind]=tanh(a); fcode[l]=konstind; ++konstind; fcode[l+1]=nop; ++vs; --pritrans; l += 2; ordnen(); --rend; break; case fasin: if( fcode[l+1]==fcx ) a=x; else if( fcode[l+1]==fcy ) a=y; else a=fkonst[fcode[l+1]]; fkonst[konstind]=asin(a); fcode[l]=konstind; ++konstind; fcode[l+1]=nop; ++vs; --pritrans; l += 2; ordnen(); --rend; break; case facos: if( fcode[l+1]==fcx ) a=x; else if( fcode[l+1]==fcy ) a=y; else a=fkonst[fcode[l+1]]; fkonst[konstind]=acos(a); fcode[l]=konstind; ++konstind; fcode[l+1]=nop; ++vs; --pritrans; l += 2; ordnen(); --rend; break; case fatan: if( fcode[l+1]==fcx ) a=x; else if( fcode[l+1]==fcy ) a=y; else a=fkonst[fcode[l+1]]; fkonst[konstind]=atan(a); fcode[l]=konstind; ++konstind; fcode[l+1]=nop; ++vs; --pritrans; l += 2; ordnen(); --rend; break; case fsqrt: if( fcode[l+1]==fcx ) a=x; else if( fcode[l+1]==fcy ) a=y; else a=fkonst[fcode[l+1]]; if(a < 0) a =0; fkonst[konstind]=sqrt(a); fcode[l]=konstind; ++konstind; fcode[l+1]=nop; ++vs; --pritrans; l += 2; ordnen(); --rend; break; case fbet: if( fcode[l+1]==fcx ) a=x; else if( fcode[l+1]==fcy ) a=y; else a=fkonst[fcode[l+1]]; fkonst[konstind]=fabs(a); fcode[l]=konstind; ++konstind; fcode[l+1]=nop; ++vs; --pritrans; l += 2; ordnen(); --rend; break; default: ++l; } } } if( prihoch > 0 ) { l=ranf; while( l < rend ) { switch(fcode[l]) { case fhoch: if( fcode[l-1]==fcx ) a=x; else if( fcode[l-1]==fcy ) a=y; else a=fkonst[fcode[l-1]]; if( fcode[l+1]==fcx ) b=x; else if( fcode[l+1]==fcy ) b=y; else b=fkonst[fcode[l+1]]; fkonst[konstind]=pow(a,b); fcode[l]=konstind; ++konstind; fcode[l-1]=nop; fcode[l+1]=nop; --prihoch; ++l; vs += 2; ordnen(); rend -= 2; break; default: ++l; } } } if( primul > 0 ) { l=ranf; while( l < rend ) { switch(fcode[l]) { case fdurch: if( fcode[l-1]==fcx ) a=x; else if( fcode[l-1]==fcy ) a=y; else a=fkonst[fcode[l-1]]; if( fcode[l+1]==fcx ) b=x; else if( fcode[l+1]==fcy ) b=y; else b=fkonst[fcode[l+1]]; if( b==0.0 ) b=1e-20; fkonst[konstind]=a/b; fcode[l]=konstind; ++konstind; fcode[l-1]=nop; fcode[l+1]=nop; --primul; ordnen(); vs += 2; rend -= 2; break; case fmal: if( fcode[l-1]==fcx ) a=x; else if( fcode[l-1]==fcy ) a=y; else a=fkonst[fcode[l-1]]; if( fcode[l+1]==fcx ) b=x; else if( fcode[l+1]==fcy ) b=y; else b=fkonst[fcode[l+1]]; fkonst[konstind]=a*b; fcode[l]=konstind; ++konstind; fcode[l-1]=nop; fcode[l+1]=nop; --primul; ordnen(); vs += 2; rend -= 2; break; default: ++l; } } } if( priadd > 0 ) { l=ranf; while( l < rend ) { switch(fcode[l]) { case fminus: if( (l==0) || (fcode[l-1]==fklamauf) ) { if(fcode[l+1]==fcx) a=x; else if(fcode[l+1]==fcy) a=y; else if(fcode[l+1] < 80) a=fkonst[fcode[l+1]]; fkonst[konstind]=-a; fcode[l]=konstind; ++konstind; --priadd; fcode[l+1]=nop; ordnen(); ++vs; --rend; break; } else { if( fcode[l-1]==fcx ) a=x; else if( fcode[l-1]==fcy ) a=y; else a=fkonst[fcode[l-1]]; if( fcode[l+1]==fcx ) b=x; else if( fcode[l+1]==fcy ) b=y; else b=fkonst[fcode[l+1]]; fkonst[konstind]=a-b; fcode[l]=konstind; ++konstind; fcode[l-1]=nop; fcode[l+1]=nop; --priadd; ordnen(); vs += 2; rend -= 2; break; } case fplus: if( fcode[l-1]==fcx ) a=x; else if( fcode[l-1]==fcy ) a=y; else a=fkonst[fcode[l-1]]; if( fcode[l+1]==fcx ) b=x; else if( fcode[l+1]==fcy ) b=y; else b=fkonst[fcode[l+1]]; fkonst[konstind]=a+b; fcode[l]=konstind; ++konstind; fcode[l-1]=nop; fcode[l+1]=nop; --priadd; ordnen(); vs += 2; rend -= 2; break; default: ++l; } } } return(vs); } void UserFunction::ordnen(void) { DWORD subzahl=0,oind1=0,oind2=0; DWORD zws[1000]; while( oind1 < codeind) { if(fcode[oind1] != (DWORD)nop) { zws[oind2]=fcode[oind1]; ++oind1; ++oind2; } else { ++oind1; ++subzahl; } } codeind -= subzahl; for(oind1=0; oind1 < codeind; ++oind1) fcode[oind1]=zws[oind1]; } DWORD UserFunction::fwandel(char *fstring) { DWORD lenght,i; int klamtest; char qw[20],t; lenght=strlen(fstring); for(i=0; i < lenght; scode[i++]=0); for(i=0; i < lenght; skonst[i++]=0.0); spritrans=sprihoch=sprimul=spriadd=0; strind=skonstind=scodeind=sklamanz=0; klamtest=0; do { t=fstring[strind]; if( (t >= '0')&&(t <='9')||(t=='.') ) { i=0; while(((fstring[strind] >='0')&&(fstring[strind]<='9'))||fstring[strind]=='.') { qw[i]=fstring[strind]; ++i; ++strind; } qw[i]='\0'; sscanf(qw,"%lf",&skonst[skonstind]); scode[scodeind]=skonstind; ++skonstind; ++scodeind; } else if(t=='+'||t=='-'||t=='*'||t=='/'||t=='^'||t=='x'||t=='y'||t=='('||t==')') { switch(fstring[strind]) { case '+': scode[scodeind]=fplus; ++scodeind; ++strind; ++spriadd; break; case '-': scode[scodeind]=fminus; ++scodeind; ++strind; ++spriadd; break; case '*': scode[scodeind]=fmal; ++scodeind; ++strind; ++sprimul; break; case '/': scode[scodeind]=fdurch; ++scodeind; ++strind; ++sprimul; break; case '^': scode[scodeind]=fhoch; ++scodeind; ++strind; ++sprihoch; break; case 'x': scode[scodeind]=fcx; ++scodeind; ++strind; break; case 'y': scode[scodeind]=fcy; ++scodeind; ++strind; break; case '(': scode[scodeind]=fklamauf; ++scodeind; ++strind; ++sklamanz; ++klamtest; break; case ')': scode[scodeind]=fklamzu; ++scodeind; ++strind; --klamtest; break; } } else if( t=='s'||t=='c'||t=='t'||t=='e'||t=='l'||t=='a' ) { if( (fstring[strind]=='s')&&(fstring[strind+1]=='i') &&(fstring[strind+2]=='n')&&(fstring[strind+3]=='h') ) { scode[scodeind]=fsinh; ++spritrans; strind += 4; ++scodeind; } else if( (fstring[strind]=='c')&&(fstring[strind+1]=='o') &&(fstring[strind+2]=='s')&&(fstring[strind+3]=='h') ) { scode[scodeind]=fcosh; ++spritrans; strind += 4; ++scodeind; } else if( (fstring[strind]=='t')&&(fstring[strind+1]=='a') &&(fstring[strind+2]=='n')&&(fstring[strind+3]=='h') ) { scode[scodeind]=ftanh; ++spritrans; strind += 4; ++scodeind; } else if( (fstring[strind]=='a')&&(fstring[strind+1]=='s') &&(fstring[strind+2]=='i')&&(fstring[strind+3]=='n') ) { scode[scodeind]=fasin; ++spritrans; strind += 4; ++scodeind; } else if( (fstring[strind]=='a')&&(fstring[strind+1]=='c') &&(fstring[strind+2]=='o')&&(fstring[strind+3]=='s') ) { scode[scodeind]=facos; ++spritrans; strind += 4; ++scodeind; } else if( (fstring[strind]=='a')&&(fstring[strind+1]=='t') &&(fstring[strind+2]=='a')&&(fstring[strind+3]=='n') ) { scode[scodeind]=fatan; ++spritrans; strind += 4; ++scodeind; } else if( (fstring[strind]=='s')&&(fstring[strind+1]=='q') &&(fstring[strind+2]=='r')&&(fstring[strind+3]=='t') ) { scode[scodeind]=fsqrt; ++spritrans; strind += 4; ++scodeind; } else if( (fstring[strind]=='a')&&(fstring[strind+1]=='b') &&(fstring[strind+2]=='s') ) { scode[scodeind]=fbet; ++spritrans; strind += 3; ++scodeind; } else if( (fstring[strind]=='s')&&(fstring[strind+1]=='i') &&(fstring[strind+2]=='n') ) { scode[scodeind]=fsin; ++spritrans; strind += 3; ++scodeind; } else if( (fstring[strind]=='c')&&(fstring[strind+1]=='o') &&(fstring[strind+2]=='s') ) { scode[scodeind]=fcos; ++spritrans; strind += 3; ++scodeind; } else if( (fstring[strind]=='t')&&(fstring[strind+1]=='a') &&(fstring[strind+2]=='n') ) { scode[scodeind]=ftan; ++spritrans; strind += 3; ++scodeind; } else if( (fstring[strind]=='e')&&(fstring[strind+1]=='x') &&(fstring[strind+2]=='p') ) { scode[scodeind]=fexp; ++spritrans; strind += 3; ++scodeind; } else if( (fstring[strind]=='l')&&(fstring[strind+1]=='n') ) { scode[scodeind]=fln; ++spritrans; strind += 2; ++scodeind; } else ++strind; } else ++strind; } while(strind < def_size); return(klamtest); } void __fastcall TForm1::Button1Click(TObject *Sender) { //????????????????????????????????????????? } //---------------------------------------------------------------------------Diesen Code habe ich runtergeladen (http://swem.de/parser.htm) und ich möchte, dass wenn der Button1 geklickt wird, dass dann für 2 vergegebene "zahlen" der funktionswert ausgegeben wird, wobei ich den funktionsterm noch (ich glaube als "str" - das ist ja der sinn der sache) angeben muss.
WIE DEKLARIERE IST DAS IN DER FUNKTION "Button1Click"????????????????????
vielen danke
gruß,
dominik
-
HobbyInformatiker schrieb:
WIE DEKLARIERE IST DAS IN DER FUNKTION "Button1Click"????????????????????
?(???????)
War das jetzt ein deutscher Satz?Also: Was du machen musst, steht in der von dir angeführten PDF auf Seite 2. Da ist sogar ein Quelltextbeispiel.
Was ist dein genaues Problem bzw. welche genauen Fehler treten auf?
[EDIT]
Nachtrag: In dem Beispiel ist meines Erachtens nach aber ein Fehler: in der äußeren for-Schleife sollte auch y als Vergleichs- bzw. Inkrementationswert dienen.
[/EDIT]
-
Ich schlage vor, du machst dir ein neues leeres Projekt.
Auf das Formular legst du ein Eingabefeld (Edit1), ein Memofeld (Memo1) und einen Button (Button1).
Du musst dann nur noch die cpp-Datei zum Projekt hinzufügen.Dann ersetzt du die Code in der Datei unit1.cpp durch den folgenden:
//--------------------------------------------------------------------------- #include <vcl.h> #include <stdio.h> #pragma hdrstop #include "Unit1.h" #include "fnkt.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma resource "*.dfm" TForm1 *Form1; UserFunction myFnkt; // // // // __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { Edit1->Text="exp(x)"; //Beispiel } // // // // void __fastcall TForm1::Button1Click(TObject *Sender) { AnsiString fktstr; AnsiString memostr; bool bReturn; char szMemoText[255]; fktstr=Edit1->Text; double xwert=0; double ywert=0; double zwert=0; bReturn=myFnkt.f_def(fktstr.c_str()); if (bReturn) { Memo1->Lines->Add(fktstr.c_str()); if (myFnkt.is_definded) //Fehler im Parser-Code (is_definded statt is_defined) { //Die Funktionsgrenzen müssten natürlich auch variabel sein. //Das ist aber wohl keine Problem for (xwert=0.0; xwert<=10.0; xwert=xwert+1.0) { zwert=myFnkt.calc(xwert); //zwert=myFnkt.calc(xwert, ywert); //Für komplexere Funktionen sprintf(szMemoText, "x=%f : y=%f", xwert, zwert); Memo1->Lines->Add(szMemoText); } } else { Memo1->Lines->Add("Fehler: Not defined"); } } else { Memo1->Lines->Add("Fehler: Parser"); } }Beachte: der Parser-Code enthält mindestens zwei Fehler:
(1) "isdefinded" statt "isdefined"
Da gibt es ein wenig durcheinander in der Dokumentation und im Quellcode.
(2) Die Winkelfunktionen erwarten die Parameter im Bogenmaß.
Auf den ersten Blick sieht es so aus als würde dies durch deinen Parser-Code
nicht berücksicht. Du müsstest die Umrechnung in allen Winkelfunktionen in
den case-Blöcken einfügen, da du ja bestimmt mit normalen kartesischen
Koordinaten arbeiten möchtest.
-
Der Parser-Code enthält einen weiteren Fehler.
Vielleicht sollte auf dieses Beispiel nicht mehr verwiesen werden.Er verarbeitet einfache Summen f(x)=x+1 oder f(x)=sin(x)+1 nicht.
Der Auswertung der Zahlen läuft anscheinend schief, den f(x)=sin(x)+sin(x) funktioniert.