00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "mathexpr.h"
00023 #include "defs.h"
00024
00025 char* MidStr(const char*s,int i1,int i2)
00026 {
00027 if(i1<0||i2>=(int)strlen(s)||i1>i2){
00028 char* cp = new char[1];
00029 cp[0] = '\0';
00030 return cp;
00031 }
00032 char*s1=new char[i2-i1+2];
00033 int i;
00034 for(i=i1;i<=i2;i++)s1[i-i1]=s[i];
00035 s1[i2-i1+1]=0;return s1;
00036 }
00037
00038 char* CopyStr(const char*s)
00039 {char*s1=new char[strlen(s)+1];char*s12=s1;const char*s2=s;
00040 while((*s12++=*s2++));return s1;}
00041
00042 void InsStr(char*&s,int n,char c)
00043 {if(n<0||n>(int)strlen(s))return;
00044 char*s1=new char[strlen(s)+2];
00045 int i;
00046 for(i=0;i<n;i++)s1[i]=s[i];
00047 s1[n]=c;for(i=n+1;s[i-1];i++)s1[i]=s[i-1];
00048 s1[i]=0;
00049 delete[]s;s=s1;
00050 }
00051
00052 signed char EqStr(const char*s,const char*s2)
00053 {if(strlen(s)!=strlen(s2))return 0;
00054 int i;
00055 for(i=0;s[i];i++)if(s[i]!=s2[i])return 0;
00056 return 1;
00057 }
00058
00059 signed char CompStr(const char*s,int n,const char*s2)
00060 {if(n<0||n>=(int)strlen(s)||n+(int)strlen(s2)>(int)strlen(s))return 0;
00061 int i;
00062 for(i=0;s2[i];i++)if(s[i+n]!=s2[i])return 0;
00063 return 1;
00064 }
00065
00066 void DelStr(char*&s,int n)
00067 {char*s1=new char[strlen(s)];
00068 int i;
00069 for(i=0;i<n;i++)s1[i]=s[i];
00070 for(i=n;s[i+1];i++)s1[i]=s[i+1];
00071 s1[i]=0;
00072 delete[]s;s=s1;
00073 }
00074
00075 RVar::RVar(const RVar & rvarp)
00076 {if(this==&rvarp)return;pval=rvarp.pval;name=CopyStr(rvarp.name);
00077 }
00078
00079 RVar::RVar(const char*namep,float*pvalp)
00080 {pval=pvalp;name=CopyStr(namep);}
00081
00082 RVar::~RVar()
00083 {if(name!=NULL)delete[] name;}
00084
00085 RFunction::RFunction()
00086 {
00087 type=-1;name=new char[1];name[0]=0;
00088 nvars=0;ppvar=NULL;pfuncval=NULL;op=ErrVal;buf=NULL;
00089 }
00090
00091 RFunction::RFunction(float ((*pfuncvalp)(float)))
00092 {
00093 type=0;pfuncval=pfuncvalp;name=new char[1];name[0]=0;
00094 nvars=1;ppvar=NULL;op=ErrVal;buf=NULL;
00095 }
00096
00097 RFunction::RFunction(const RFunction& rfunc)
00098 {
00099 if(this==&rfunc)return;
00100 type=rfunc.type;op=rfunc.op;
00101 pfuncval=rfunc.pfuncval;
00102 name=CopyStr(rfunc.name);
00103 nvars=rfunc.nvars;
00104 if(rfunc.ppvar!=NULL&&nvars){
00105 ppvar=new PRVar[nvars];
00106 int i;for(i=0;i<nvars;i++)ppvar[i]=rfunc.ppvar[i];
00107 buf=new float[nvars];
00108 }else {ppvar=NULL;buf=NULL;}
00109 }
00110
00111 RFunction::RFunction(const ROperation& opp,RVar* pvarp):op(opp)
00112 {
00113 type=1;name=new char[1];name[0]=0;
00114 nvars=1;ppvar=new PRVar[1];ppvar[0]=pvarp;buf=new float[1];
00115 }
00116
00117 RFunction::RFunction(const ROperation& opp, int nvarsp,RVar**ppvarp):op(opp)
00118 {
00119 type=1;name=new char[1];name[0]=0;
00120 nvars=nvarsp;
00121 if(nvars){
00122 ppvar=new PRVar[nvars];
00123 int i;for(i=0;i<nvars;i++)ppvar[i]=ppvarp[i];
00124 buf=new float[nvars];
00125 }else {ppvar=NULL;buf=NULL;}
00126 }
00127
00128 RFunction::~RFunction()
00129 {
00130 if(name!=NULL)delete[]name;
00131 if(ppvar!=NULL)delete[]ppvar;
00132 if(buf!=NULL)delete[]buf;
00133 }
00134
00135 RFunction& RFunction::operator=(const RFunction& rfunc)
00136 {
00137 if(this==&rfunc)return *this;
00138 type=rfunc.type;op=rfunc.op;
00139 pfuncval=rfunc.pfuncval;
00140 delete[]name;
00141 name=CopyStr(rfunc.name);
00142 if(ppvar!=NULL)delete[]ppvar;
00143 ppvar=NULL;
00144 if(buf!=NULL)delete[]buf;
00145 buf=NULL;
00146 nvars=rfunc.nvars;
00147 if(type==1&&nvars){
00148 ppvar=new PRVar[nvars];buf=new float[nvars];
00149 int i;for(i=0;i<nvars;i++)ppvar[i]=rfunc.ppvar[i];
00150 }
00151 return *this;
00152 }
00153
00154 void RFunction::SetName(const char*s)
00155 {if(name!=NULL)delete[]name;name=CopyStr(s);}
00156
00157 float RFunction::Val(float x) const
00158 {
00159 if(type==-1||nvars>=2)return ErrVal;
00160 if(type==0)return (*pfuncval)(x);
00161 float xb=*(*ppvar)->pval,y;
00162 *(*ppvar)->pval=x;
00163 y=op.Val();
00164 *(*ppvar)->pval=xb;
00165 return y;
00166 }
00167
00168 float RFunction::Val(float*pv) const
00169 {
00170 if(type==-1)return ErrVal;
00171 if(type==0)return (*pfuncval)(*pv);
00172 float y;
00173 int i;
00174 for(i=0;i<nvars;i++){
00175 buf[i]=*ppvar[i]->pval;
00176
00177 *ppvar[i]->pval=pv[i];
00178 }
00179 y=op.Val();
00180 for(i=0;i<nvars;i++)*ppvar[i]->pval=buf[i];
00181 return y;
00182 }
00183
00184 ROperation::ROperation()
00185 {op=ErrOp;mmb1=NULL;mmb2=NULL;ValC=ErrVal;pvar=NULL;pvarval=NULL;pfunc=NULL;containfuncflag=0;pinstr=NULL;pvals=NULL;ppile=NULL;pfuncpile=NULL;BuildCode();}
00186
00187 ROperation::~ROperation()
00188 {
00189 Destroy();
00190 }
00191
00192 ROperation::ROperation(const ROperation&ROp)
00193 {
00194 op=ROp.op;pvar=ROp.pvar;pvarval=ROp.pvarval;ValC=ROp.ValC;pfunc=ROp.pfunc;containfuncflag=0;pinstr=NULL;pvals=NULL;ppile=NULL;pfuncpile=NULL;
00195 if(ROp.mmb1!=NULL)mmb1=new ROperation(*(ROp.mmb1));else mmb1=NULL;
00196 if(ROp.mmb2!=NULL)mmb2=new ROperation(*(ROp.mmb2));else mmb2=NULL;
00197 BuildCode();
00198 }
00199
00200 ROperation::ROperation(float x)
00201 {
00202 if(x==ErrVal){op=ErrOp;mmb1=NULL;mmb2=NULL;ValC=ErrVal;}
00203 else if(x>=0){op=Num;mmb1=NULL;mmb2=NULL;ValC=x;}
00204 else{op=Opp;mmb1=NULL;mmb2=new ROperation(-x);ValC=ErrVal;}
00205 pvar=NULL;pvarval=NULL;pfunc=NULL;containfuncflag=0;pinstr=NULL;pvals=NULL;ppile=NULL;pfuncpile=NULL;
00206 BuildCode();
00207 }
00208
00209 ROperation::ROperation(const RVar&varp)
00210 {op=Var;mmb1=NULL;mmb2=NULL;ValC=ErrVal;pvar=&varp;pvarval=varp.pval;containfuncflag=0;pfunc=NULL;pinstr=NULL;pvals=NULL;ppile=NULL;pfuncpile=NULL;BuildCode();}
00211
00212 ROperation& ROperation::operator=(const ROperation& ROp)
00213 {
00214 if(this==&ROp)return *this;
00215 Destroy();
00216 op=ROp.op;pvar=ROp.pvar;pvarval=ROp.pvarval;ValC=ROp.ValC;pfunc=ROp.pfunc;containfuncflag=0;pinstr=NULL;pvals=NULL;ppile=NULL;pfuncpile=NULL;
00217 if(ROp.mmb1!=NULL)mmb1=new ROperation(*(ROp.mmb1));else mmb1=NULL;
00218 if(ROp.mmb2!=NULL)mmb2=new ROperation(*(ROp.mmb2));else mmb2=NULL;
00219 BuildCode();
00220 return *this;
00221 }
00222
00223 int operator==(const ROperation& op,const float v)
00224 {return(op.op==Num&&op.ValC==v);}
00225
00226 int operator==(const ROperation& op1,const ROperation& op2)
00227 {if(op1.op!=op2.op)return 0;
00228 if(op1.op==Var)return(*(op1.pvar)==*(op2.pvar));
00229 if(op1.op==Fun)return(op1.pfunc==op2.pfunc);
00230 if(op1.op==Num)return(op1.ValC==op2.ValC);
00231 if(op1.mmb1==NULL&&op2.mmb1!=NULL)return 0;
00232 if(op1.mmb2==NULL&&op2.mmb2!=NULL)return 0;
00233 if(op2.mmb1==NULL&&op1.mmb1!=NULL)return 0;
00234 if(op2.mmb2==NULL&&op1.mmb2!=NULL)return 0;
00235 return(((op1.mmb1==NULL&&op2.mmb1==NULL)||(*(op1.mmb1)==*(op2.mmb1)))&&
00236 ((op1.mmb2==NULL&&op2.mmb2==NULL)||(*(op1.mmb2)==*(op2.mmb2))));
00237 }
00238
00239 int operator!=(const ROperation& op1,const ROperation& op2)
00240 {
00241 if(op1.op!=op2.op)return 1;
00242 if(op1.op==Var)return(op1.pvar!=op2.pvar);
00243 if(op1.op==Fun)return(!(op1.pfunc==op2.pfunc));
00244 if(op1.op==Num)return(op1.ValC!=op2.ValC);
00245 if(op1.mmb1==NULL&&op2.mmb1!=NULL)return 1;
00246 if(op1.mmb2==NULL&&op2.mmb2!=NULL)return 1;
00247 if(op2.mmb1==NULL&&op1.mmb1!=NULL)return 1;
00248 if(op2.mmb2==NULL&&op1.mmb2!=NULL)return 1;
00249 return(((op1.mmb1!=NULL||op2.mmb1!=NULL)&&(*(op1.mmb1)!=*(op2.mmb1)))||
00250 ((op1.mmb2!=NULL||op2.mmb2!=NULL)&&(*(op1.mmb2)!=*(op2.mmb2))));
00251 }
00252
00253 ROperation ROperation::operator+() const
00254 {return *this;}
00255
00256 ROperation ROperation::operator-() const
00257 {if(op==Num)return -ValC;
00258 ROperation resultat;
00259 if(op==Opp)resultat=*mmb2;else{resultat.op=Opp;resultat.mmb2=new ROperation(*this);};
00260 return resultat;
00261 }
00262
00263 ROperation operator,(const ROperation& op1,const ROperation& op2)
00264 {ROperation resultat;
00265 resultat.op=Juxt;resultat.mmb1=new ROperation(op1);
00266 resultat.mmb2=new ROperation(op2);
00267 return resultat;
00268 }
00269
00270 ROperation operator+(const ROperation& op1,const ROperation& op2)
00271 {
00272 if(op1.op==Num&&op2.op==Num)return op1.ValC+op2.ValC;
00273 if(op1==0.)return op2;if(op2==0.)return op1;
00274 if(op1.op==Opp)return op2-*(op1.mmb2);if(op2.op==Opp)return op1-*(op2.mmb2);
00275 ROperation resultat;
00276 resultat.op=Add;resultat.mmb1=new ROperation(op1);
00277 resultat.mmb2=new ROperation(op2);
00278 return resultat;
00279 }
00280
00281 ROperation operator-(const ROperation& op1,const ROperation& op2)
00282 {
00283 if(op1.op==Num&&op2.op==Num)return op1.ValC-op2.ValC;
00284 if(op1==0.)return -op2;if(op2==0.)return op1;
00285 if(op1.op==Opp)return -(op2+*(op1.mmb2));if(op2.op==Opp)return op1+*(op2.mmb2);
00286 ROperation resultat;
00287 resultat.op=Sub;resultat.mmb1=new ROperation(op1);
00288 resultat.mmb2=new ROperation(op2);
00289 return resultat;
00290 }
00291
00292 ROperation operator*(const ROperation& op1,const ROperation& op2)
00293 {
00294 if(op1.op==Num&&op2.op==Num)return op1.ValC*op2.ValC;
00295 if(op1==0.||op2==0.)return 0.;
00296 if(op1==1.)return op2;if(op2==1.)return op1;
00297 if(op1.op==Opp)return -(*(op1.mmb2)*op2);if(op2.op==Opp)return -(op1**(op2.mmb2));
00298 ROperation resultat;
00299 resultat.op=Mult;resultat.mmb1=new ROperation(op1);
00300 resultat.mmb2=new ROperation(op2);
00301 return resultat;
00302 }
00303
00304 ROperation operator/(const ROperation& op1,const ROperation& op2)
00305 {if(op1.op==Num&&op2.op==Num)return (op2.ValC?op1.ValC/op2.ValC:ErrVal);
00306 if(op1==0.0)return 0.;if(op2==1.)return op1;if(op2==0.)return ErrVal;
00307 if(op1.op==Opp)return -(*(op1.mmb2)/op2);if(op2.op==Opp)return -(op1/(*(op2.mmb2)));
00308 ROperation resultat;
00309 resultat.op=Div;resultat.mmb1=new ROperation(op1);
00310 resultat.mmb2=new ROperation(op2);
00311 return resultat;
00312 }
00313
00314 ROperation operator^(const ROperation& op1,const ROperation& op2)
00315 {if(op1==0.)return 0.;
00316 if(op2==0.)return 1.;
00317 if(op2==1.)return op1;
00318 ROperation resultat;
00319 resultat.op=Pow;resultat.mmb1=new ROperation(op1);
00320 resultat.mmb2=new ROperation(op2);
00321 return resultat;
00322 }
00323
00324 ROperation sqrt(const ROperation& op)
00325 {ROperation rop;rop.op=Sqrt;rop.mmb2=new ROperation(op);return rop;}
00326 ROperation abs(const ROperation& op)
00327 {ROperation rop;rop.op=Abs;rop.mmb2=new ROperation(op);return rop;}
00328 ROperation sin(const ROperation& op)
00329 {ROperation rop;rop.op=Sin;rop.mmb2=new ROperation(op);return rop;}
00330 ROperation cos(const ROperation& op)
00331 {ROperation rop;rop.op=Cos;rop.mmb2=new ROperation(op);return rop;}
00332 ROperation tan(const ROperation& op)
00333 {ROperation rop;rop.op=Tg;rop.mmb2=new ROperation(op);return rop;}
00334 ROperation log(const ROperation& op)
00335 {ROperation rop;rop.op=Ln;rop.mmb2=new ROperation(op);return rop;}
00336 ROperation exp(const ROperation& op)
00337 {ROperation rop;rop.op=Exp;rop.mmb2=new ROperation(op);return rop;}
00338 ROperation acos(const ROperation& op)
00339 {ROperation rop;rop.op=Acos;rop.mmb2=new ROperation(op);return rop;}
00340 ROperation asin(const ROperation& op)
00341 {ROperation rop;rop.op=Asin;rop.mmb2=new ROperation(op);return rop;}
00342 ROperation atan(const ROperation& op)
00343 {ROperation rop;rop.op=Atan;rop.mmb2=new ROperation(op);return rop;}
00344
00345 ROperation ApplyOperator(int n,ROperation**pops,ROperation (*func)(const ROperation&,const ROperation&))
00346 {
00347 if(n<=0)return ErrVal;
00348 if(n==1)return *pops[0];
00349 if(n==2)return (*func)(*pops[0],*pops[1]);
00350 return (*func)(*pops[0],ApplyOperator(n-1,pops+1,func));
00351 }
00352
00353 ROperation RFunction::operator()(const ROperation& op)
00354 {
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371 ROperation op2;op2.op=Fun;op2.pfunc=this;op2.mmb2=new ROperation(op);
00372 return op2;
00373 }
00374
00375
00376
00377 void SupprSpaces(char*&s)
00378 {
00379 int i;
00380 for(i=0;s[i];i++)if(s[i]==' '||s[i]=='\t'||s[i]=='\n')DelStr(s,i--);
00381 }
00382
00383 signed char IsNumeric(char c)
00384 {if(c!='0'&&c!='1'&&c!='2'&&c!='3'&&c!='4'
00385 &&c!='5'&&c!='6'&&c!='7'&&c!='8'&&c!='9'&&c!='.')return 0;
00386 return 1;
00387 }
00388
00389 signed char IsTNumeric(char *s)
00390 {int i;for(i=0;i<(int)strlen(s);i++)if(!IsNumeric(s[i]))return 0;return 1;
00391 }
00392
00393 int SearchCorOpenbracket(char*s,int n)
00394 {if(n>=(int)strlen(s)-1)return -1;
00395 int i,c=1;
00396 for(i=n+1;s[i];i++){
00397 if(s[i]=='(')c++;else if(s[i]==')')c--;
00398 if(!c)return i;
00399 };
00400 return -1;
00401 }
00402
00403 int SearchCorClosebracket(char*s,int n)
00404 {if(n<1)return -1;
00405 int i,c=1;
00406 for(i=n-1;i>=0;i--){
00407 if(s[i]==')')c++;else if(s[i]=='(')c--;
00408 if(!c)return i;
00409 };
00410 return -1;
00411 }
00412
00413 int SearchOperator(char*s,ROperator op)
00414 {
00415 char opc;
00416 switch(op){
00417 case ErrOp:case Num:case Var:return -1;
00418 case Juxt:opc=',';break;
00419 case Add:opc='+';break;
00420 case Sub:opc='-';break;
00421 case Mult:opc='*';break;
00422 case Div:opc='/';break;
00423 case Pow:opc='^';break;
00424 case NthRoot:opc='#';break;
00425 case E10:opc='E';break;
00426 default:return -1;
00427 };
00428 int i;
00429 for(i=(int)strlen(s)-1;i>=0;i--){
00430 if(s[i]==opc&&(op!=Sub||i&&s[i-1]==')'))return i;
00431 if(s[i]==')'){i=SearchCorClosebracket(s,i);if(i==-1)return -1;};
00432 };
00433 return -1;
00434 }
00435
00436 void SimplifyStr(char*&s)
00437 {if(!strlen(s))return;
00438 char*s1=s,*s2=s+strlen(s);signed char ind=0;
00439 if(s1[0]=='('&&SearchCorOpenbracket(s1,0)==s2-s1-1){
00440 s1++;s2--;ind=1;}
00441 if(s1==s2)
00442 {
00443 delete[]s;
00444 s=new char[1];
00445 s[0]=0;
00446 return;
00447 }
00448 if(s1[0]==' '){ind=1;while(s1[0]==' '&&s1<s2)s1++;}
00449 if(s1==s2)
00450 {
00451 delete[]s;
00452 s=new char[1];
00453 s[0]=0;
00454 return;
00455 }
00456 if(*(s2-1)==' '){ind=1;while(s2>s1&&*(s2-1)==' ')s2--;}
00457 *s2=0;
00458 s1=CopyStr(s1);delete[]s;s=s1;
00459 if(ind)SimplifyStr(s);
00460 }
00461
00462 int max(int a, int b){return (a>b?a:b);}
00463
00464 int IsVar(const char*s,int n,int nvar,PRVar*ppvar)
00465 {
00466 if(n<0||n>(int)strlen(s))return 0;
00467 int i;int l=0;
00468 for(i=0;i<nvar;i++)if(CompStr(s,n,(*(ppvar+i))->name))l=max(l,strlen((*(ppvar+i))->name));
00469 return l;
00470 }
00471
00472 int IsFunction(const char*s,int n)
00473 {
00474 if(CompStr(s,n,"sin")||CompStr(s,n,"cos")||CompStr(s,n,"exp")
00475 ||CompStr(s,n,"tan")||CompStr(s,n,"log")||CompStr(s,n,"atg")
00476 ||CompStr(s,n,"abs"))return 3;
00477 if(CompStr(s,n,"tg")||CompStr(s,n,"ln"))return 2;
00478 if(CompStr(s,n,"sqrt")||CompStr(s,n,"asin")||CompStr(s,n,"atan")||
00479 CompStr(s,n,"acos"))return 4;
00480 if(CompStr(s,n,"arcsin")||CompStr(s,n,"arccos")||CompStr(s,n,"arctan"))return 6;
00481 if(CompStr(s,n,"arctg"))return 5;
00482 return 0;
00483 }
00484
00485 int IsFunction(const char*s,int n,int nfunc,PRFunction*ppfunc)
00486
00487
00488
00489
00490 {
00491 int l=IsFunction(s,n);
00492 if(l)return l;
00493 int i;l=0;
00494 for(i=0;i<nfunc;i++)if(CompStr(s,n,ppfunc[i]->name))l=max(l,strlen(ppfunc[i]->name));
00495 return l;
00496 }
00497
00498 signed char IsFunction(ROperator op)
00499 {return (op==Exp||op==Abs||op==Sin||op==Cos||op==Tg||op==Ln||
00500 op==Atan||op==Asin||op==Acos||op==Atan||op==Sqrt||op==Opp);
00501 }
00502
00503 void IsolateVars(char*&s,int nvar,PRVar*ppvar,int nfunc,PRFunction*ppfunc)
00504 {
00505 int i,j;
00506 i=0;
00507 for(i=0;s[i];i++){
00508 if(s[i]=='('){i=SearchCorOpenbracket(s,i);if(i==-1)return;continue;};
00509 if(((j=IsVar(s,i,nvar,ppvar))>IsFunction(s,i,nfunc,ppfunc))||((CompStr(s,i,"pi")||CompStr(s,i,"PI")||CompStr(s,i,"Pi"))&&(j=2))){
00510 InsStr(s,i,'(');InsStr(s,i+j+1,')');i+=j+1;continue;};
00511 if(IsFunction(s,i,nfunc,ppfunc)){i+=IsFunction(s,i,nfunc,ppfunc)-1;if(!s[i])return;continue;};
00512 };
00513 }
00514
00515 void IsolateNumbers(char*&s,int nvar,RVar**ppvar,int nfunc,RFunction**ppfunc)
00516 {
00517 int i,i2,ind=0,t1,t2;
00518
00519 i2=42;
00520 for(i=0;s[i];i++){
00521 if(ind&&!IsNumeric(s[i])){ind=0;InsStr(s,i2,'(');i++;InsStr(s,i,')');continue;};
00522 t1=IsVar(s,i,nvar,ppvar);t2=IsFunction(s,i,nfunc,ppfunc);
00523 if(t1||t2){i+=max(t1,t2)-1;continue;};
00524 if(s[i]=='('){i=SearchCorOpenbracket(s,i);if(i==-1)return;continue;};
00525 if(!ind&&IsNumeric(s[i])){i2=i;ind=1;};
00526 };
00527 if(ind)InsStr(s,i2,'(');i++;InsStr(s,i,')');
00528 }
00529
00530 ROperation::ROperation(char const*sp,int nvar,PRVar*ppvarp,int nfuncp,PRFunction*ppfuncp)
00531 {
00532 ValC=ErrVal;mmb1=NULL;mmb2=NULL;pvar=NULL;op=ErrOp;pvarval=NULL;containfuncflag=0;pfunc=NULL;pinstr=NULL;pvals=NULL;ppile=NULL;pfuncpile=NULL;
00533 int i,j,k,l;signed char flag=1;
00534 char*s=CopyStr(sp),*s1=NULL,*s2=NULL;
00535 SimplifyStr(s);if(!s[0]||!strcmp(s,"Error")){goto fin;}
00536 while(s[0]==':'||s[0]==';'){
00537 s1=CopyStr(s+1);delete[]s;s=s1;s1=NULL;
00538 SimplifyStr(s);if(!s[0]||!strcmp(s,"Error")){goto fin;}
00539 }
00540 if(IsTNumeric(s)){op=Num;ValC=atof(s);mmb1=NULL;mmb2=NULL;goto fin;};
00541 if(EqStr(s,"pi")||EqStr(s,"PI")||EqStr(s,"Pi"))
00542 {op=Num;ValC=3.141592653589793238462643383279L;mmb1=NULL;mmb2=NULL;goto fin;};
00543 if(IsFunction(s,0,nfuncp,ppfuncp)<IsVar(s,0,nvar,ppvarp))
00544 for(i=0;i<nvar;i++)if(EqStr(s,(*(ppvarp+i))->name))
00545 {pvar=ppvarp[i];pvarval=pvar->pval;op=Var;mmb1=NULL;mmb2=NULL;goto fin;};
00546 for(k=0;s[k];k++){
00547 if(s[k]=='('){k=SearchCorOpenbracket(s,k);if(k==-1)break;continue;};
00548 if((l=IsFunction(s,k,nfuncp,ppfuncp))&&l>=IsVar(s,k,nvar,ppvarp)){
00549 i=k+l;while(s[i]==' ')i++;
00550 if(s[i]=='('){
00551 j=SearchCorOpenbracket(s,i);
00552 if(j!=-1){InsStr(s,i,';');k=j+1;}else break;
00553 }else if(s[i]!=':'&&s[i]!=';'){InsStr(s,i,':');k=i;}
00554 }
00555 }
00556 IsolateNumbers(s,nvar,ppvarp,nfuncp,ppfuncp);
00557 if(nvar)IsolateVars(s,nvar,ppvarp,nfuncp,ppfuncp);
00558 SupprSpaces(s);
00559 i=SearchOperator(s,Juxt);
00560 if(i!=-1){s1=MidStr(s,0,i-1);s2=MidStr(s,i+1,strlen(s)-1);
00561 op=Juxt;mmb1=new ROperation(s1,nvar,ppvarp,nfuncp,ppfuncp);
00562 mmb2=new ROperation(s2,nvar,ppvarp,nfuncp,ppfuncp);goto fin;
00563 };
00564 i=SearchOperator(s,Add);
00565 if(i!=-1){s1=MidStr(s,0,i-1);s2=MidStr(s,i+1,strlen(s)-1);
00566 op=Add;mmb1=new ROperation(s1,nvar,ppvarp,nfuncp,ppfuncp);
00567 mmb2=new ROperation(s2,nvar,ppvarp,nfuncp,ppfuncp);goto fin;
00568 };
00569 i=SearchOperator(s,Sub);
00570 if(i!=-1){
00571 s1=MidStr(s,0,i-1);s2=MidStr(s,i+1,strlen(s)-1);
00572 op=Sub;mmb1=new ROperation(s1,nvar,ppvarp,nfuncp,ppfuncp);
00573 mmb2=new ROperation(s2,nvar,ppvarp,nfuncp,ppfuncp);goto fin;
00574 };
00575 if(s[0]=='-'){s2=MidStr(s,1,strlen(s)-1);
00576 op=Opp;mmb1=NULL;
00577 mmb2=new ROperation(s2,nvar,ppvarp,nfuncp,ppfuncp);goto fin;
00578 };
00579 for(i=0;s[i];i++){
00580 if(s[i]=='('){i=SearchCorOpenbracket(s,i);if(i==-1)break;continue;};
00581 if(IsFunction(s,i,nfuncp,ppfuncp)){
00582 k=i+IsFunction(s,i,nfuncp,ppfuncp);while(s[k]==' ')k++;
00583 if(s[k]==';'){
00584
00585 j=k;while(s[j]!='(')j++;
00586 j=SearchCorOpenbracket(s,j);
00587 if(j!=-1){InsStr(s,j,')');InsStr(s,i,'(');i=j+2;}
00588 }else if(s[k]==':'){
00589
00590 for(j=k;s[j];j++)
00591 if(s[j]=='('){j=SearchCorOpenbracket(s,j);break;}
00592 if(j==-1)break;
00593 for(j++;s[j];j++){
00594 if(s[j]=='('){j=SearchCorOpenbracket(s,j);if(j==-1){flag=0;break;};continue;};
00595 if(IsFunction(s,j,nfuncp,ppfuncp))break;
00596 }
00597 if(flag==0){flag=1;break;}
00598 while(j>i&&s[j-1]!=')')j--;if(j<=i+1)break;
00599 InsStr(s,i,'(');InsStr(s,j+1,')');
00600 i=j+1;
00601 }
00602 }
00603 }
00604 for(i=0;s[i]&&s[i+1];i++)if(s[i]==')'&&s[i+1]=='(')
00605 InsStr(s,++i,'*');
00606 if(s[0]=='('&&SearchCorOpenbracket(s,0)==(int)strlen(s)-1){
00607 if(CompStr(s,1,"exp")){op=Exp;s2=MidStr(s,4,strlen(s)-2);}
00608 else if(CompStr(s,1,"abs")){op=Abs;s2=MidStr(s,4,strlen(s)-2);}
00609 else if(CompStr(s,1,"sin")){op=Sin;s2=MidStr(s,4,strlen(s)-2);}
00610 else if(CompStr(s,1,"cos")){op=Cos;s2=MidStr(s,4,strlen(s)-2);}
00611 else if(CompStr(s,1,"tan")){op=Tg;s2=MidStr(s,4,strlen(s)-2);}
00612 else if(CompStr(s,1,"log")){op=Ln;s2=MidStr(s,4,strlen(s)-2);}
00613 else if(CompStr(s,1,"atg")){op=Atan;s2=MidStr(s,4,strlen(s)-2);}
00614 else if(CompStr(s,1,"tg")){op=Tg;s2=MidStr(s,3,strlen(s)-2);}
00615 else if(CompStr(s,1,"ln")){op=Ln;s2=MidStr(s,3,strlen(s)-2);}
00616 else if(CompStr(s,1,"asin")){op=Asin;s2=MidStr(s,5,strlen(s)-2);}
00617 else if(CompStr(s,1,"acos")){op=Acos;s2=MidStr(s,5,strlen(s)-2);}
00618 else if(CompStr(s,1,"atan")){op=Atan;s2=MidStr(s,5,strlen(s)-2);}
00619 else if(CompStr(s,1,"sqrt")){op=Sqrt;s2=MidStr(s,5,strlen(s)-2);}
00620 else if(CompStr(s,1,"arcsin")){op=Asin;s2=MidStr(s,7,strlen(s)-2);}
00621 else if(CompStr(s,1,"arccos")){op=Acos;s2=MidStr(s,7,strlen(s)-2);}
00622 else if(CompStr(s,1,"arctan")){op=Atan;s2=MidStr(s,7,strlen(s)-2);}
00623 else if(CompStr(s,1,"arctg")){op=Atan;s2=MidStr(s,6,strlen(s)-2);}
00624 else {
00625 for(i=-1,k=0,j=0;j<nfuncp;j++)if(CompStr(s,1,ppfuncp[j]->name)&&k<(int)strlen(ppfuncp[j]->name)){k=strlen(ppfuncp[j]->name);i=j;}
00626 if(i>-1){
00627 op=Fun;s2=MidStr(s,strlen(ppfuncp[i]->name)+1,strlen(s)-2);
00628 pfunc=ppfuncp[i];
00629 }
00630 }
00631 mmb1=NULL;mmb2=new ROperation(s2,nvar,ppvarp,nfuncp,ppfuncp);
00632 if(op==Fun)if(mmb2->NMembers()!=pfunc->nvars){op=ErrOp;mmb1=NULL;mmb2=NULL;goto fin;}
00633 goto fin;
00634 };
00635 i=SearchOperator(s,Mult);
00636 if(i!=-1){s1=MidStr(s,0,i-1);s2=MidStr(s,i+1,strlen(s)-1);
00637 op=Mult;mmb1=new ROperation(s1,nvar,ppvarp,nfuncp,ppfuncp);
00638 mmb2=new ROperation(s2,nvar,ppvarp,nfuncp,ppfuncp);goto fin;
00639 };
00640 i=SearchOperator(s,Div);
00641 if(i!=-1){s1=MidStr(s,0,i-1);s2=MidStr(s,i+1,strlen(s)-1);
00642 op=Div;mmb1=new ROperation(s1,nvar,ppvarp,nfuncp,ppfuncp);
00643 mmb2=new ROperation(s2,nvar,ppvarp,nfuncp,ppfuncp);goto fin;
00644 };
00645 i=SearchOperator(s,Pow);
00646 if(i!=-1){s1=MidStr(s,0,i-1);s2=MidStr(s,i+1,strlen(s)-1);
00647 op=Pow;mmb1=new ROperation(s1,nvar,ppvarp,nfuncp,ppfuncp);
00648 mmb2=new ROperation(s2,nvar,ppvarp,nfuncp,ppfuncp);goto fin;
00649 };
00650 i=SearchOperator(s,NthRoot);
00651 if(i!=-1){s1=MidStr(s,0,i-1);s2=MidStr(s,i+1,strlen(s)-1);
00652 if(i==0||s[i-1]!=')')
00653 {op=Sqrt;mmb1=NULL;}else
00654 {op=NthRoot;mmb1=new ROperation(s1,nvar,ppvarp,nfuncp,ppfuncp);};
00655 mmb2=new ROperation(s2,nvar,ppvarp,nfuncp,ppfuncp);goto fin;
00656 };
00657 i=SearchOperator(s,E10);
00658 if(i!=-1){s1=MidStr(s,0,i-1);s2=MidStr(s,i+1,strlen(s)-1);
00659 op=E10;mmb1=new ROperation(s1,nvar,ppvarp,nfuncp,ppfuncp);
00660 mmb2=new ROperation(s2,nvar,ppvarp,nfuncp,ppfuncp);goto fin;
00661 };
00662 op=ErrOp;mmb1=NULL;mmb2=NULL;
00663 fin:
00664 BuildCode();
00665 delete[]s;if(s1!=NULL)delete[] s1;if(s2!=NULL)delete[]s2;
00666 }
00667
00668 void ROperation::Destroy()
00669 {
00670 if(mmb1!=NULL&&mmb2!=NULL&&mmb1!=mmb2){delete mmb1;delete mmb2;mmb1=NULL;mmb2=NULL;}
00671 else if(mmb1!=NULL){delete mmb1;mmb1=NULL;}else if(mmb2!=NULL){delete mmb2;mmb2=NULL;}
00672 if(pinstr!=NULL){delete[]pinstr;pinstr=NULL;}
00673 if(pvals!=NULL){
00674 if(op==ErrOp||op==Num)delete pvals[0];
00675 delete[]pvals;pvals=NULL;
00676 }
00677 if(ppile!=NULL){delete[]ppile;ppile=NULL;}
00678 if(pfuncpile!=NULL){delete[]pfuncpile;pfuncpile=NULL;}
00679 }
00680
00681 int operator==(const RVar& var1,const RVar& var2)
00682 {return(var1.pval==var2.pval&&EqStr(var1.name,var2.name));
00683 }
00684
00685 int operator==(const RFunction& f1,const RFunction& f2)
00686 {
00687 if(f1.type!=f2.type)return 0;
00688 if(f1.type==-1)return 1;
00689 if(f1.type==0)return (f1.pfuncval==f2.pfuncval&&EqStr(f1.name,f2.name));
00690 if(f1.op!=f2.op)return 0;
00691 if(!EqStr(f1.name,f2.name))return 0;
00692 if(f1.nvars!=f2.nvars)return 0;
00693 int i;
00694 for(i=0;i<f1.nvars;i++)if(!(*f1.ppvar[i]==*f2.ppvar[i]))return 0;
00695 return 1;
00696 }
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706
00707
00708
00709
00710
00711
00712
00713
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734 signed char ROperation::ContainVar(const RVar& varp) const
00735 {if(op==Var){if(EqStr(pvar->name,varp.name)&&pvar->pval==varp.pval)
00736 return 1;else return 0;};
00737 if(mmb1!=NULL&&mmb1->ContainVar(varp))return 1;
00738 if(mmb2!=NULL&&mmb2->ContainVar(varp))return 1;
00739 return 0;
00740 }
00741
00742 signed char ROperation::ContainFuncNoRec(const RFunction& func) const
00743 {if(op==Fun){if(*pfunc==func)
00744 return 1;else return 0;}
00745 if(mmb1!=NULL&&mmb1->ContainFuncNoRec(func))return 1;
00746 if(mmb2!=NULL&&mmb2->ContainFuncNoRec(func))return 1;
00747 return 0;
00748 }
00749
00750 signed char ROperation::ContainFunc(const RFunction& func) const
00751 {
00752 if(containfuncflag)return 0;
00753 if(op==Fun&&*pfunc==func)return 1;
00754 containfuncflag=1;
00755 if(op==Fun)if(pfunc->op.ContainFunc(func)){containfuncflag=0;return 1;}
00756 if(mmb1!=NULL&&mmb1->ContainFunc(func)){containfuncflag=0;return 1;}
00757 if(mmb2!=NULL&&mmb2->ContainFunc(func)){containfuncflag=0;return 1;}
00758 containfuncflag=0;return 0;
00759 }
00760
00761 signed char ROperation::HasError(const ROperation*pop) const
00762 {
00763 if(op==ErrOp)return 1;
00764 if(op==Fun&&pfunc->type==1&&pfunc->op==*(pop==NULL?this:pop))return 1;
00765 if(op==Fun&&pfunc->type==1&&pfunc->op.HasError((pop==NULL?this:pop)))return 1;
00766 if(mmb1!=NULL&&mmb1->HasError((pop==NULL?this:pop)))return 1;
00767 if(mmb2!=NULL&&mmb2->HasError((pop==NULL?this:pop)))return 1;
00768 if(op==Fun&&pfunc->type==-1)return 1;
00769 return 0;
00770 }
00771
00772 int ROperation::NMembers() const
00773 {
00774 if(op==Fun)return(pfunc->type==1?pfunc->op.NMembers():pfunc->type==0?1:0);
00775 if(op!=Juxt)return 1;else if(mmb2==NULL)return 0;else return 1+mmb2->NMembers();
00776 }
00777
00778 ROperation ROperation::NthMember(int n) const
00779 {
00780 PRFunction prf;
00781 if(op==Fun&&pfunc->type==1&&pfunc->op.NMembers()>1){
00782 prf=new RFunction(pfunc->op.NthMember(n),pfunc->nvars,pfunc->ppvar);
00783 char*s=new char[strlen(pfunc->name)+10];
00784 sprintf(s,"(%s_%i)",pfunc->name,n);prf->SetName(s);delete[]s;
00785 return(*prf)(*mmb2);
00786 }
00787 if(n==1){
00788 if(op!=Juxt)return *this; else if(mmb1!=NULL)return *mmb1;else return ErrVal;
00789 };
00790 if(op!=Juxt)return ErrVal;
00791 if(n>1&&mmb2!=NULL)return mmb2->NthMember(n-1);
00792 return ErrVal;
00793 }
00794
00795 ROperation ROperation::Substitute(const RVar& var,const ROperation& rop) const
00796 {
00797 if(!ContainVar(var))return *this;
00798 if(op==Var)return rop;
00799 ROperation r;
00800 r.op=op;r.pvar=pvar;r.pvarval=pvarval;r.ValC=ValC;r.pfunc=pfunc;
00801 if(mmb1!=NULL)r.mmb1=new ROperation(mmb1->Substitute(var,rop));else r.mmb1=NULL;
00802 if(mmb2!=NULL)r.mmb2=new ROperation(mmb2->Substitute(var,rop));else r.mmb2=NULL;
00803 return r;
00804 }
00805
00806 ROperation ROperation::Diff(const RVar& var) const
00807 {
00808 if(!ContainVar(var))return 0.0;
00809 if(op==Var)return 1.0;
00810 ROperation **ppop1,op2;int i,j;
00811 switch(op){
00812 case Juxt:return(mmb1->Diff(var),mmb2->Diff(var));
00813 case Add:return(mmb1->Diff(var)+mmb2->Diff(var));
00814 case Sub:return(mmb1->Diff(var)-mmb2->Diff(var));
00815 case Opp:return(-mmb2->Diff(var));
00816 case Mult:return((*mmb1)*(mmb2->Diff(var))+(*mmb2)*(mmb1->Diff(var)));
00817 case Div:if(mmb2->ContainVar(var))return(((*mmb2)*(mmb1->Diff(var))-(*mmb1)*(mmb2->Diff(var)))/((*mmb2)^2));
00818 else return(mmb1->Diff(var)/(*mmb2));
00819 case Pow:if(mmb2->ContainVar(var))return((*this)*(log(*mmb1)*mmb2->Diff(var)+
00820 (*mmb2)*mmb1->Diff(var)/(*mmb1)));else
00821 return (*mmb2)*mmb1->Diff(var)*((*mmb1)^(*mmb2-1));
00822 case Sqrt:return(mmb2->Diff(var)/(2*sqrt(*mmb2)));
00823 case NthRoot:{ROperation interm=(*mmb2)^(1/(*mmb1));return interm.Diff(var);};
00824 case E10:{ROperation interm=(*mmb1)*(10^(*mmb2));return interm.Diff(var);};;
00825 case Ln:return (mmb2->Diff(var)/(*mmb2));
00826 case Exp:return (mmb2->Diff(var)*(*this));
00827 case Sin:return (mmb2->Diff(var)*cos(*mmb2));
00828 case Cos:return (-mmb2->Diff(var)*sin(*mmb2));
00829 case Tg:return (mmb2->Diff(var)*(1+((*this)^2)));
00830 case Atan:
00831 if(mmb2->op!=Juxt)return(mmb2->Diff(var)/(1+((*mmb2)^2)));
00832 else return ((mmb2->NthMember(1).Diff(var))*(mmb2->NthMember(2))-(mmb2->NthMember(2).Diff(var))*(mmb2->NthMember(1)))/(((mmb2->NthMember(1))^2)+((mmb2->NthMember(2))^2));
00833 case Asin:return(mmb2->Diff(var)/sqrt(1-((*mmb2)^2)));
00834 case Acos:return(-mmb2->Diff(var)/sqrt(1-((*mmb2)^2)));
00835 case Abs:return(mmb2->Diff(var)*(*mmb2)/(*this));
00836 case Fun:if(pfunc->type==-1||pfunc->type==0)return ErrVal;
00837 if(pfunc->nvars==0)return 0.;
00838 else if(pfunc->op.NMembers()>1){
00839 j=pfunc->op.NMembers();
00840 ppop1=new ROperation*[j];
00841 for(i=0;i<j;i++)ppop1[i]=new ROperation(NthMember(i+1).Diff(var));
00842 op2=ApplyOperator(pfunc->nvars,ppop1,&operator,);
00843 for(i=0;i<pfunc->nvars;i++)delete ppop1[i];
00844 delete[]ppop1;
00845 return op2;
00846 }else{
00847 ppop1=new ROperation*[pfunc->nvars];
00848 for(i=0;i<pfunc->nvars;i++){
00849 ppop1[i]=new ROperation(pfunc->op.Diff(*pfunc->ppvar[i]));
00850 for(j=0;j<pfunc->nvars;j++)
00851 *ppop1[i]=ppop1[i]->Substitute(*pfunc->ppvar[j],mmb2->NthMember(j+1));
00852 *ppop1[i]=(mmb2->NthMember(i+1).Diff(var))*(*ppop1[i]);
00853 }
00854 op2=ApplyOperator(pfunc->nvars,ppop1,&::operator+);
00855 for(i=0;i<pfunc->nvars;i++)delete ppop1[i];
00856 delete[]ppop1;
00857 return op2;
00858
00859 }
00860 default:return ErrVal;
00861 };
00862 }
00863
00864 char* ValToStr(float x)
00865 {
00866 char*s=new char[30];
00867 if(x==(float)3.141592653589793238462643383279L)sprintf(s,"pi");else sprintf(s,"%.16G",x);
00868 return s;
00869 }
00870
00871 char* ROperation::Expr() const
00872 {
00873 char*s=NULL,*s1=NULL,*s2=NULL;int n=10;signed char f=0,g=0;
00874 if(op==Fun)if(strlen(pfunc->name)>4)n+=strlen(pfunc->name)-4;
00875 if(mmb1!=NULL){s1=mmb1->Expr();n+=strlen(s1);f=IsFunction(mmb1->op);}
00876 if(mmb2!=NULL){s2=mmb2->Expr();n+=strlen(s2);g=IsFunction(mmb2->op);}
00877 s=new char[n];
00878 switch(op){
00879 case Num:return ValToStr(ValC);
00880 case Var:return CopyStr(pvar->name);
00881 case Juxt:sprintf(s,"%s , %s",s1,s2);break;
00882 case Add:
00883 f=f||(mmb1->op==Juxt);
00884 g=g||(mmb2->op==Juxt);
00885 if(f&&g)sprintf(s,"(%s)+(%s)",s1,s2);else
00886 if(f)sprintf(s,"(%s)+%s",s1,s2);else
00887 if(g)sprintf(s,"%s+(%s)",s1,s2);else
00888 sprintf(s,"%s+%s",s1,s2);
00889 break;
00890 case Sub:
00891 f=f||(mmb1->op==Juxt);
00892 g=g||(mmb2->op==Juxt||mmb2->op==Add||mmb2->op==Sub);
00893 if(f&&g)sprintf(s,"(%s)-(%s)",s1,s2);else
00894 if(f)sprintf(s,"(%s)-%s",s1,s2);else
00895 if(g)sprintf(s,"%s-(%s)",s1,s2);else
00896 sprintf(s,"%s-%s",s1,s2);
00897 break;
00898 case Opp:
00899 if(mmb2->op==Add||mmb2->op==Sub||mmb2->op==Juxt)sprintf(s,"-(%s)",s2);else
00900 sprintf(s,"-%s",s2);
00901 break;
00902 case Mult:
00903 f=f||(mmb1->op==Juxt||mmb1->op==Add||mmb1->op==Sub||mmb1->op==Opp||mmb1->op==Div);
00904 g=g||(mmb2->op==Juxt||mmb2->op==Add||mmb2->op==Sub||mmb2->op==Opp);
00905 if(f&&g)sprintf(s,"(%s)*(%s)",s1,s2);else
00906 if(f)sprintf(s,"(%s)*%s",s1,s2);else
00907 if(g)sprintf(s,"%s*(%s)",s1,s2);else
00908 sprintf(s,"%s*%s",s1,s2);
00909 break;
00910 case Div:
00911 f=f||(mmb1->op==Juxt||mmb1->op==Add||mmb1->op==Sub||mmb1->op==Opp||mmb1->op==Div);
00912 g=g||(mmb2->op==Juxt||mmb2->op==Add||mmb2->op==Sub||mmb2->op==Opp||mmb2->op==Mult||mmb2->op==Div);
00913 if(f&&g)sprintf(s,"(%s)/(%s)",s1,s2);else
00914 if(f)sprintf(s,"(%s)/%s",s1,s2);else
00915 if(g)sprintf(s,"%s/(%s)",s1,s2);else
00916 sprintf(s,"%s/%s",s1,s2);
00917 break;
00918 case Pow:
00919 f=(mmb1->op!=Num&&mmb1->op!=Var);
00920 g=(mmb2->op!=Num&&mmb2->op!=Var);
00921 if(f&&g)sprintf(s,"(%s)^(%s)",s1,s2);else
00922 if(f)sprintf(s,"(%s)^%s",s1,s2);else
00923 if(g)sprintf(s,"%s^(%s)",s1,s2);else
00924 sprintf(s,"%s^%s",s1,s2);
00925 break;
00926 case Sqrt:
00927 g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
00928 if(g)sprintf(s,"sqrt(%s)",s2);
00929 else sprintf(s,"sqrt %s",s2);
00930 break;
00931 case NthRoot:
00932 f=(mmb1->op!=Num&&mmb1->op!=Var);
00933 g=(mmb2->op!=Num&&mmb2->op!=Var);
00934 if(f&&g)sprintf(s,"(%s)#(%s)",s1,s2);else
00935 if(f)sprintf(s,"(%s)#%s",s1,s2);else
00936 if(g)sprintf(s,"%s#(%s)",s1,s2);else
00937 sprintf(s,"%s#%s",s1,s2);
00938 break;
00939 case E10:
00940 f=(mmb1->op!=Num&&mmb1->op!=Var);
00941 g=(mmb2->op!=Num&&mmb2->op!=Var);
00942 if(f&&g)sprintf(s,"(%s)E(%s)",s1,s2);else
00943 if(f)sprintf(s,"(%s)E%s",s1,s2);else
00944 if(g)sprintf(s,"%sE(%s)",s1,s2);else
00945 sprintf(s,"%sE%s",s1,s2);
00946 break;
00947 case Ln:
00948 g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
00949 if(g)sprintf(s,"log(%s)",s2);
00950 else sprintf(s,"log %s",s2);
00951 break;
00952 case Exp:
00953 g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
00954 if(g)sprintf(s,"exp(%s)",s2);
00955 else sprintf(s,"exp %s",s2);
00956 break;
00957 case Sin:
00958 g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
00959 if(g)sprintf(s,"sin(%s)",s2);
00960 else sprintf(s,"sin %s",s2);
00961 break;
00962 case Cos:
00963 g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
00964 if(g)sprintf(s,"cos(%s)",s2);
00965 else sprintf(s,"cos %s",s2);
00966 break;
00967 case Tg:
00968 g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
00969 if(g)sprintf(s,"tan(%s)",s2);
00970 else sprintf(s,"tan %s",s2);
00971 break;
00972 case Atan:
00973 g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
00974 if(g)sprintf(s,"atan(%s)",s2);
00975 else sprintf(s,"atan %s",s2);
00976 break;
00977 case Asin:
00978 g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
00979 if(g)sprintf(s,"asin(%s)",s2);
00980 else sprintf(s,"asin %s",s2);
00981 break;
00982 case Acos:
00983 g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
00984 if(g)sprintf(s,"acos(%s)",s2);
00985 else sprintf(s,"acos %s",s2);
00986 break;
00987 case Abs:
00988 g=(mmb2->op!=Num&&mmb2->op!=Var&&!g);
00989 if(g)sprintf(s,"abs(%s)",s2);
00990 else sprintf(s,"abs %s",s2);
00991 break;
00992 case Fun:
00993 sprintf(s,"%s(%s)",pfunc->name,s2);
00994 break;
00995 default:return CopyStr("Error");
00996 };
00997 if(s1!=NULL)delete[] s1;if(s2!=NULL)delete[] s2;
00998 return s;
00999 }
01000
01001 const float sqrtmaxfloat=sqrt(DBL_MAX);
01002 const float sqrtminfloat=sqrt(DBL_MIN);
01003 const float inveps=.1/DBL_EPSILON;
01004
01005 void Addition(float*&p)
01006 {if(*p==ErrVal||fabs(*p)>sqrtmaxfloat){*(--p)=ErrVal;return;};
01007 if(*(--p)==ErrVal||fabs(*p)>sqrtmaxfloat){*p=ErrVal;return;};
01008 *p+=(*(p+1));}
01009 void Soustraction(float*&p)
01010 {if(*p==ErrVal||fabs(*p)>sqrtmaxfloat){*(--p)=ErrVal;return;};
01011 if(*(--p)==ErrVal||fabs(*p)>sqrtmaxfloat){*p=ErrVal;return;};
01012 *p-=(*(p+1));}
01013 void Multiplication(float*&p)
01014 {if(fabs(*p)<sqrtminfloat){*--p=0;return;};
01015 if(*p==ErrVal||fabs(*p)>sqrtmaxfloat){*(--p)=ErrVal;return;};
01016 if(fabs(*(--p))<sqrtminfloat){*p=0;return;};
01017 if(*p==ErrVal||fabs(*p)>sqrtmaxfloat){*p=ErrVal;return;};
01018 *p*=(*(p+1));}
01019 void Division(float*&p)
01020 {if(fabs(*p)<sqrtminfloat||*p==ErrVal||fabs(*p)>sqrtmaxfloat)
01021 {*(--p)=ErrVal;return;};
01022 if(fabs(*(--p))<sqrtminfloat)*p=0;else if(*p==ErrVal||fabs(*p)>sqrtmaxfloat)
01023 {*p=ErrVal;return;};
01024 *p/=(*(p+1));}
01025 void Puissance(float*&p)
01026 {float v2=*p--,v1=*p;
01027 if(!v1){*p=0;return;};
01028 if(v2==ErrVal||v1==ErrVal||fabs(v2*log(fabs(v1)))>DBL_MAX_EXP){*p=ErrVal;return;};
01029 *p=((v1>0||!fmod(v2,1))?pow(v1,v2):ErrVal);}
01030 void RacineN(float*&p)
01031 {float v2=*p--,v1=*p;
01032 if(v1==ErrVal||v2==ErrVal||!v1||v2*log(fabs(v1))<DBL_MIN_EXP){*p=ErrVal;return;};
01033 if(v2>=0){*p=pow(v2,1/v1);return;};
01034 *p=((fabs(fmod(v1,2))==1)?-pow(-v2,1/v1):ErrVal);}
01035 void Puiss10(float*&p)
01036 {if(fabs(*p)<sqrtminfloat){*(--p)=0;return;};
01037 if(*p==ErrVal||fabs(*p)>DBL_MAX_10_EXP){*(--p)=ErrVal;return;};
01038 if(fabs(*(--p))<sqrtminfloat)*p=0;else if(*p==ErrVal||fabs(*p)>sqrtmaxfloat)
01039 {*p=ErrVal;return;};
01040 *p*=pow10(*(p+1));}
01041 void ArcTangente2(float*&p)
01042 {if(*p==ErrVal||fabs(*p)>inveps){*(--p)=ErrVal;return;};
01043 if(*(--p)==ErrVal||fabs(*p)>inveps){*p=ErrVal;return;};
01044 *p=(*p||*(p+1)?atan2(*p,*(p+1)):ErrVal);}
01045 void NextVal(float*&){}
01046 void RFunc(float*&){}
01047 void JuxtF(float*&){}
01048 void Absolu(float*&p){*p=((*p==ErrVal)?ErrVal:fabs(*p));}
01049 void Oppose(float*&p){*p=((*p==ErrVal)?ErrVal:-*p);}
01050 void ArcSinus(float*&p)
01051 {*p=((*p==ErrVal||fabs(*p)>1)?ErrVal:asin(*p));}
01052 void ArcCosinus(float*&p)
01053 {*p=((*p==ErrVal||fabs(*p)>1)?ErrVal:acos(*p));}
01054 void ArcTangente(float*&p)
01055 {*p=((*p==ErrVal)?ErrVal:atan(*p));}
01056 void Logarithme(float*&p)
01057 {*p=((*p==ErrVal||*p<=0)?ErrVal:log(*p));}
01058 void Exponentielle(float*&p)
01059 {*p=((*p==ErrVal||*p>DBL_MAX_EXP)?ErrVal:exp(*p));}
01060 void Sinus(float*&p)
01061 {*p=((*p==ErrVal||fabs(*p)>inveps)?ErrVal:sin(*p));}
01062 void Tangente(float*&p)
01063 {*p=((*p==ErrVal||fabs(*p)>inveps)?ErrVal:tan(*p));}
01064 void Cosinus(float*&p)
01065 {*p=((*p==ErrVal||fabs(*p)>inveps)?ErrVal:cos(*p));}
01066 void Racine(float*&p)
01067 {*p=((*p==ErrVal||*p>sqrtmaxfloat||*p<0)?ErrVal:sqrt(*p));}
01068 void FonctionError(float*&p){*p=ErrVal;}
01069 inline void ApplyRFunc(PRFunction rf,float*&p)
01070 {p-=rf->nvars-1;*p=rf->Val(p);}
01071
01072 float ROperation::Val() const
01073 {
01074 pfoncld*p1=pinstr;float**p2=pvals,*p3=ppile-1;PRFunction*p4=pfuncpile;
01075 for(;*p1!=NULL;p1++)
01076 if(*p1==&NextVal)*(++p3)=**(p2++);else
01077 if(*p1==&RFunc) ApplyRFunc(*(p4++),p3);
01078 else (**p1)(p3);
01079 return *p3;
01080 }
01081
01082 void BCDouble(pfoncld*&pf,pfoncld*pf1,pfoncld*pf2,
01083 float**&pv,float**pv1,float**pv2,
01084 float*&pp,float*pp1,float*pp2,
01085 RFunction**&prf,RFunction**prf1,RFunction**prf2,
01086 pfoncld f)
01087 {
01088 pfoncld*pf3,*pf4=pf1;long n1,n2;
01089 for(n1=0;*pf4!=NULL;pf4++,n1++);for(n2=0,pf4=pf2;*pf4!=NULL;pf4++,n2++);
01090 pf=new pfoncld[n1+n2+2];
01091 for(pf3=pf,pf4=pf1;*pf4!=NULL;pf3++,pf4++)*pf3=*pf4;
01092 for(pf4=pf2;*pf4!=NULL;pf3++,pf4++)*pf3=*pf4;
01093 *pf3++=f;*pf3=NULL;
01094 float**pv3,**pv4=pv1;
01095 for(n1=0;*pv4!=NULL;pv4++,n1++);for(n2=0,pv4=pv2;*pv4!=NULL;pv4++,n2++);
01096 pv=new float*[n1+n2+1];
01097 for(pv3=pv,pv4=pv1;*pv4!=NULL;pv3++,pv4++)*pv3=*pv4;
01098 for(pv4=pv2;*pv4!=NULL;pv3++,pv4++)*pv3=*pv4;
01099 *pv3=NULL;
01100 float*pp3,*pp4=pp1;
01101 for(n1=0;*pp4!=ErrVal;pp4++,n1++);for(n2=0,pp4=pp2;*pp4!=ErrVal;pp4++,n2++);
01102 pp=new float[n1+n2+1];
01103 for(pp3=pp,pp4=pp1;*pp4!=ErrVal;pp3++,pp4++)*pp3=0;
01104 for(pp4=pp2;*pp4!=ErrVal;pp3++,pp4++)*pp3=0;
01105 *pp3=ErrVal;
01106 PRFunction*prf3,*prf4=prf1;
01107 for(n1=0;*prf4!=NULL;prf4++,n1++);for(n2=0,prf4=prf2;*prf4!=NULL;prf4++,n2++);
01108 prf=new PRFunction[n1+n2+1];
01109 for(prf3=prf,prf4=prf1;*prf4!=NULL;prf3++,prf4++)*prf3=*prf4;
01110 for(prf4=prf2;*prf4!=NULL;prf3++,prf4++)*prf3=*prf4;
01111 *prf3=NULL;
01112 }
01113
01114 void BCSimple(pfoncld*&pf,pfoncld*pf1,float**&pv,float**pv1,
01115 float*&pp,float*pp1,RFunction**&prf,RFunction**prf1,pfoncld f)
01116 {
01117 pfoncld*pf3,*pf4=pf1;long n;
01118 for(n=0;*pf4!=NULL;pf4++,n++);
01119 pf=new pfoncld[n+2];
01120 for(pf4=pf1,pf3=pf;*pf4!=NULL;pf3++,pf4++)*pf3=*pf4;
01121 *pf3++=f;*pf3=NULL;
01122 float**pv3,**pv4=pv1;
01123 for(n=0;*pv4!=NULL;pv4++,n++);
01124 pv=new float*[n+1];
01125 for(pv3=pv,pv4=pv1;*pv4!=NULL;pv3++,pv4++)*pv3=*pv4;
01126 *pv3=NULL;
01127 float*pp3,*pp4=pp1;
01128 for(n=0;*pp4!=ErrVal;pp4++,n++);
01129 pp=new float[n+1];
01130 for(pp3=pp,pp4=pp1;*pp4!=ErrVal;pp3++,pp4++)*pp3=0;
01131 *pp3=ErrVal;
01132 RFunction**prf3,**prf4=prf1;
01133 for(n=0;*prf4!=NULL;prf4++,n++);
01134 prf=new RFunction*[n+1];
01135 for(prf3=prf,prf4=prf1;*prf4!=NULL;prf3++,prf4++)*prf3=*prf4;
01136 *prf3=NULL;
01137 }
01138
01139 void BCFun(pfoncld*&pf,pfoncld*pf1,float**&pv,float**pv1,
01140 float*&pp,float*pp1,RFunction**&prf,RFunction**prf1,PRFunction rf)
01141 {
01142 pfoncld*pf3,*pf4=pf1;long n;
01143 for(n=0;*pf4!=NULL;pf4++,n++);
01144 pf=new pfoncld[n+2];
01145 for(pf4=pf1,pf3=pf;*pf4!=NULL;pf3++,pf4++)*pf3=*pf4;
01146 *pf3++=&RFunc;*pf3=NULL;
01147 float**pv3,**pv4=pv1;
01148 for(n=0;*pv4!=NULL;pv4++,n++);
01149 pv=new float*[n+1];
01150 for(pv3=pv,pv4=pv1;*pv4!=NULL;pv3++,pv4++)*pv3=*pv4;
01151 *pv3=NULL;
01152 float*pp3,*pp4=pp1;
01153 for(n=0;*pp4!=ErrVal;pp4++,n++);
01154 pp=new float[n+1];
01155 for(pp3=pp,pp4=pp1;*pp4!=ErrVal;pp3++,pp4++)*pp3=0;
01156 *pp3=ErrVal;
01157 PRFunction*prf3,*prf4=prf1;
01158 for(n=0;*prf4!=NULL;prf4++,n++);
01159 prf=new PRFunction[n+2];
01160 for(prf4=prf1,prf3=prf;*prf4!=NULL;prf3++,prf4++)*prf3=*prf4;
01161 *prf3++=rf;*prf3=NULL;
01162 }
01163
01164 void ROperation::BuildCode()
01165 {
01166
01167 if(pinstr!=NULL){delete[]pinstr;pinstr=NULL;}
01168 if(pvals!=NULL){delete[]pvals;pvals=NULL;}
01169 if(ppile!=NULL){delete[]ppile;ppile=NULL;}
01170 if(pfuncpile!=NULL){delete[]pfuncpile;pfuncpile=NULL;}
01171 switch(op){
01172 case ErrOp:pinstr=new pfoncld[2];pinstr[0]=&NextVal;pinstr[1]=NULL;
01173 pvals=new float*[2];pvals[0]=new float(ErrVal);pvals[1]=NULL;
01174 ppile=new float[2];ppile[0]=0;ppile[1]=ErrVal;
01175 pfuncpile=new RFunction*[1];pfuncpile[0]=NULL;
01176 break;
01177 case Num:pinstr=new pfoncld[2];pinstr[0]=&NextVal;pinstr[1]=NULL;
01178 pvals=new float*[2];pvals[0]=new float(ValC);pvals[1]=NULL;
01179 ppile=new float[2];ppile[0]=0;ppile[1]=ErrVal;
01180 pfuncpile=new RFunction*[1];pfuncpile[0]=NULL;break;
01181 case Var:pinstr=new pfoncld[2];pinstr[0]=&NextVal;pinstr[1]=NULL;
01182 pvals=new float*[2];pvals[0]=pvarval;pvals[1]=NULL;
01183 ppile=new float[2];ppile[0]=0;ppile[1]=ErrVal;
01184 pfuncpile=new RFunction*[1];pfuncpile[0]=NULL;break;
01185 case Juxt:BCDouble(pinstr,mmb1->pinstr,mmb2->pinstr,
01186 pvals,mmb1->pvals,mmb2->pvals,ppile,mmb1->ppile,mmb2->ppile,pfuncpile,mmb1->pfuncpile,mmb2->pfuncpile,&JuxtF);
01187 break;case Add:BCDouble(pinstr,mmb1->pinstr,mmb2->pinstr,
01188 pvals,mmb1->pvals,mmb2->pvals,ppile,mmb1->ppile,mmb2->ppile,pfuncpile,mmb1->pfuncpile,mmb2->pfuncpile,&Addition);
01189 break;case Sub:BCDouble(pinstr,mmb1->pinstr,mmb2->pinstr,
01190 pvals,mmb1->pvals,mmb2->pvals,ppile,mmb1->ppile,mmb2->ppile,pfuncpile,mmb1->pfuncpile,mmb2->pfuncpile,&Soustraction);
01191 break;case Mult:BCDouble(pinstr,mmb1->pinstr,mmb2->pinstr,
01192 pvals,mmb1->pvals,mmb2->pvals,ppile,mmb1->ppile,mmb2->ppile,pfuncpile,mmb1->pfuncpile,mmb2->pfuncpile,&Multiplication);
01193 break;case Div:BCDouble(pinstr,mmb1->pinstr,mmb2->pinstr,
01194 pvals,mmb1->pvals,mmb2->pvals,ppile,mmb1->ppile,mmb2->ppile,pfuncpile,mmb1->pfuncpile,mmb2->pfuncpile,&Division);
01195 break;case Pow:BCDouble(pinstr,mmb1->pinstr,mmb2->pinstr,
01196 pvals,mmb1->pvals,mmb2->pvals,ppile,mmb1->ppile,mmb2->ppile,pfuncpile,mmb1->pfuncpile,mmb2->pfuncpile,&Puissance);
01197 break;case NthRoot:BCDouble(pinstr,mmb1->pinstr,mmb2->pinstr,
01198 pvals,mmb1->pvals,mmb2->pvals,ppile,mmb1->ppile,mmb2->ppile,pfuncpile,mmb1->pfuncpile,mmb2->pfuncpile,&RacineN);
01199 break;case E10:BCDouble(pinstr,mmb1->pinstr,mmb2->pinstr,
01200 pvals,mmb1->pvals,mmb2->pvals,ppile,mmb1->ppile,mmb2->ppile,pfuncpile,mmb1->pfuncpile,mmb2->pfuncpile,&Puiss10);
01201 break;case Opp:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01202 ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&Oppose);
01203 break;case Sin:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01204 ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&Sinus);
01205 break;case Sqrt:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01206 ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&Racine);
01207 break;case Ln:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01208 ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&Logarithme);
01209 break;case Exp:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01210 ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&Exponentielle);
01211 break;case Cos:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01212 ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&Cosinus);
01213 break;case Tg:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01214 ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&Tangente);
01215 break;case Atan:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01216 ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,(mmb2->NMembers()>1?&ArcTangente2:&ArcTangente));
01217 break;case Asin:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01218 ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&ArcSinus);
01219 break;case Acos:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01220 ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&ArcCosinus);
01221 break;case Abs:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01222 ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&Absolu);
01223 break;case Fun:BCFun(pinstr,mmb2->pinstr,pvals,mmb2->pvals,ppile,
01224 mmb2->ppile,pfuncpile,mmb2->pfuncpile,pfunc);
01225 break;default:BCSimple(pinstr,mmb2->pinstr,pvals,mmb2->pvals,
01226 ppile,mmb2->ppile,pfuncpile,mmb2->pfuncpile,&FonctionError);
01227 }
01228 }