src/thirdparty/mathexpr/mathexpr.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 mathexpr.cpp version 2.0
00004 
00005 Copyright Yann OLLIVIER 1997-2000
00006 
00007 This software may be freely distributed as is, including this whole notice.
00008 
00009 It may be modified, but any modification should include this whole 
00010 notice as is and a description of the changes made.
00011 
00012 This software may not be sold.
00013 
00014 This software or any modified version of it may befreely used in free 
00015 programs. The program should include a copy of this whole notice.
00016 If you want to use it in a program you sell, contact me
00017 
00018 This software comes with absolutely no warranty.
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)// Warning : deletes the old string
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)//Deletes the old string
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;  // Warning : could cause trouble if this value is used in a parallel process
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         // Warning : could cause trouble if this value is used in a parallel process
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); // *op1.pfunc==*op2.pfunc could imply infinite loops in cases of self-dependence
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)); // *op1.pfunc==*op2.pfunc could imply infinite loops in cases of self-dependence
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     /* Code to use to replace expcitly instead of using a pointer to
00356        if(nvars!=op.NMembers()||type==-1||type==0)return ErrVal;
00357        ROperation op2=*pop;int i;
00358        RVar**ppvar2=new PRVar[nvars];char s[11]="";
00359        for(i=0;i<nvars;i++){
00360        sprintf(s,";var%i;",i);
00361        ppvar2[i]=new RVar(s,NULL);
00362        op2=op2.Substitute(*ppvar[i],(ROperation)*ppvar2[i]);
00363        }
00364        for(i=0;i<nvars;i++){
00365        op2=op2.Substitute(*ppvar2[i],op.NthMember(i+1));
00366        delete ppvar2[i];
00367        }
00368        delete[]ppvar2;
00369        return op2;
00370     */
00371     ROperation op2;op2.op=Fun;op2.pfunc=this;op2.mmb2=new ROperation(op);
00372     return op2;
00373 }
00374 
00375 //Auxiliary string functions
00376 
00377 void SupprSpaces(char*&s)//Deletes the old string
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)  //Searchs the corresponding bracket of an opening bracket
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)  //Searchs the corresponding bracket of a closing bracket
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) //Warning : deletes the old string
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]; // ISO C++ forbids initialization in array new
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]; // ISO C++ forbids initialization in array new
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 //Not recognized if a user-defined function is eg "sine" ie begins like
00487 //a standard function
00488 //IF PATCHED TO DO OTHERWISE, SHOULD BE PATCHED TOGETHER WITH THE
00489 //PARSER BELOW which treats standard functions before user-defined ones
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)//Deletes the old string
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)//Deletes the old string
00516 {
00517     int i,i2,ind=0,t1,t2;
00518     //initialize i2 to fix a wrong compiler warning
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                 //      s=DelStr(s,k);
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                 //      s=DelStr(s,k);
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; // Nonfunction==nonfunction
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 float ROperation::Val() const // Won't work if multi-variable functions are included
00700 {
00701   float v1=ErrVal,v2=ErrVal;
00702   if(mmb1!=NULL){v1=mmb1->Val();if(fabs(v1)<sqrtminfloat)v1=0;else if(v1==ErrVal||fabs(v1)>sqrtmaxfloat)return ErrVal;};
00703   if(mmb2!=NULL){v2=mmb2->Val();if(fabs(v2)<sqrtminfloat)v2=0;else if(v2==ErrVal||fabs(v2)>sqrtmaxfloat)return ErrVal;};
00704   switch(op){
00705   case Num:return ValC;
00706   case Var:return *pvarval;
00707   case Add:return v1+v2;
00708   case Sub:return v1-v2;
00709   case Opp:return -v2;
00710   case Mult:return v1*v2;
00711   case Div:if(v2)return v1/v2;else return ErrVal;
00712   case Pow:if(v1==0)return 0;else if((v1>0||!fmod(v2,1))&&v2*log(fabs(v1))<DBL_MAX_EXP)return pow(v1,v2);else return ErrVal;
00713   case Sqrt:if(v2>=0)return sqrt(v2);else return ErrVal;
00714   case NthRoot:if(!v1||v2*log(fabs(v1))<DBL_MIN_EXP)return ErrVal;
00715   else if(v2>=0)return pow(v2,1/v1);else
00716     if(fmod(v1,2)==1||fmod(v1,2)==-1)return -pow(-v2,1/v1);else return ErrVal;
00717   case E10:if(v2<DBL_MAX_10_EXP)return v1*pow10(v2);else return ErrVal;
00718   case Ln:if(v2>0)return log(v2);else return ErrVal;
00719   case Exp:if(v2<DBL_MAX_EXP)return exp(v2);else return ErrVal;
00720   case Sin:if(fabs(v2)<inveps)return sin(v2);else return ErrVal;
00721   case Cos:if(fabs(v2)<inveps)return cos(v2);else return ErrVal;
00722   case Tg:if(fabs(v2)<inveps)return tan(v2);else return ErrVal;
00723   case Atan:
00724     if(mmb2->op==Juxt){v1=mmb2->NthMember(1).Val();v2=mmb2->NthMember(2).Val();return (v1||v2?atan2(v1,v2):ErrVal);}else return atan(v2);
00725   case Asin:if(v2<-1||v2>1)return ErrVal;else return asin(v2);
00726   case Acos:if(v2<-1||v2>1)return ErrVal;else return acos(v2);
00727   case Abs:return fabs(v2);
00728   case Fun:return pfunc->Val(v2);
00729   default:return ErrVal;
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 // No recursive test on subfunctions
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 // Recursive test on subfunctions
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 //Number of members for an operation like a,b,c...
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 // Replaces variable var with expression rop
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             // In the obtained expression, f' will have been replaced with its expression but f will remain pointing to itself ; this could cause some trouble if changing f afterwards
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;//delete[]pf1,pf2;
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;//delete[]pv1,pv2;
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];  // Really need to add and not to take max(n1,n2) in case of Juxt operator
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;//delete[]pp1,pp2;
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;//delete[]prf1,prf2;
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;//delete[]pf1;
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;//delete[]pv1;
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;//delete[]pp1;
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;//delete[]prf1;
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;//delete[]pf1;
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;//delete[]pv1;
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;//delete[]pp1;
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;//delete[]pf1;
01162 }
01163 
01164 void ROperation::BuildCode()
01165 {
01166     //  if(mmb1!=NULL)mmb1->BuildCode();if(mmb2!=NULL)mmb2->BuildCode();
01167     if(pinstr!=NULL){delete[]pinstr;pinstr=NULL;}
01168     if(pvals!=NULL){delete[]pvals;pvals=NULL;}//does not delete pvals[0] in case it was to be deleted... (no way to know)
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 }

Generated on Sat Mar 15 22:55:57 2008 for Armagetron Advanced by  doxygen 1.5.4