Мат. фоpмулы

From
Petr Prokofev (2:5025/54.26)
To
All
Date
2000-03-02T22:41:40Z
Area
RU.ALGORITHMS
Решил я числа Чет Маp 02 2000 примерно в 22:41 письмо написать..

Приветствую тебя, All!


Тут много говоpили о сабже. Вот pешил пpогу, скоpее не пpогу, а набоp функций для вычисления значений выpажений.
Пpога писалась для постpоения гpафиков, поэтому вычисляет выpажение в зависимости от значений Х.
Сначала необходимо "загpузить" функцию от Х с помощью функции
FX(char*in,char*out); Напpимеp FX('ln(sin(x)*5^x)',NULL);
А затем можно получить ее значение от Х с помощью Vir(x);
Включил все стандаpтные мат. функции( какие знал (куpс 11 класса)): син,кос, аpк..., лог, експ,танг,котг,показательную (^)...
Может кому понадобится. Если у кого заpаботает и будут глюки пpосьба сообщить.
Гpафики получаются кpасивые:)

=== Cut ===

#include <stdio.h>
#include <math.h>

#define E_ZERO -1;
#define E_LN -2;
#define E_LG -3;
#define E_TG -4;
#define E_CTG -5;
#define E_STEP -6;
#define E_ABS -7;
#define E_ARC -8;

BOOL Error=FALSE;



struct element
{
float  count;
char  oper;
char*  type;
};





element e[500];
element t[500];

float Vir(float x);
BOOL FX(char*in,char*out);
void SetX(float x);


long Delete(element* e,long pos,long count)
{
 for (long i=pos+1;i<count;i++)e[i-1]=e[i];

return  count-1;
};



void SetX(float x)
{
 memcpy(t,e,sizeof(element)*Num);

 for (int i=0;i<Num;i++)
  if (strcmp("X",t[i].type)==0)
 {
  t[i].count=x;
  t[i].type=strdup("COUNT");
 }else
  if (strcmp("-X",t[i].type)==0)
 {
  t[i].count=-x;
  t[i].type=strdup("COUNT");
 }


};

void SetY(float y)
{
 memcpy(t,e,sizeof(element)*Num);

 for (int i=0;i<Num;i++)
  if (strcmp("Y",t[i].type)==0)
 {
  t[i].count=y;
  t[i].type=strdup("COUNT");
 }else
  if (strcmp("-Y",t[i].type)==0)
 {
  t[i].count=-y;
  t[i].type=strdup("COUNT");
 }


};


float step(float c,long n)
{
 long i;
 float l=1.0f;
 if (n>0)
 for (i=0;i<n;i++)l*=c; else for (i=0;i<n;i++)l/=c;
 return l;
};


int fx(element*e,int len)
{
 int l=0,i=0,f;
 while (e[i].oper!='=')
       i++;
 l=i+1;

 while ((e[i].type[0]!='(')&&(e[i].type[0]!='|'))
       i--;
 f=i+1;

 i=f;
 while (i<l)
    if (e[i].oper=='&')
     {
      e[i].oper=e[i+1].oper;


      if (strcmp(e[i].type,"LN")==0)if (e[i+1].count>0)e[i].count=log(e[i+1].count);else return E_LN;
      if (strcmp(e[i].type,"LG")==0)if (e[i+1].count>0)e[i].count=log10(e[i+1].count);else return E_LG;
      if (strcmp(e[i].type,"SIN")==0)e[i].count=sin(e[i+1].count);
      if (strcmp(e[i].type,"COS")==0)e[i].count=cos(e[i+1].count);
      if (strcmp(e[i].type,"TG")==0)if (cos(e[i+1].count)!=0)e[i].count=tan(e[i+1].count);else return E_TG;
      if (strcmp(e[i].type,"CTG")==0)if (sin(e[i+1].count)!=0)e[i].count=1/tan(e[i+1].count);else return E_CTG;
      if (strcmp(e[i].type,"ARCSIN")==0)if((e[i+1].count>=-1)&&(e[i+1].count<=1))e[i].co unt=asin(e[i+1].count);else return E_ARC;
      if (strcmp(e[i].type,"ARCCOS")==0)if((e[i+1].count>=-1)&&(e[i+1].count<=1))e[i].co unt=acos(e[i+1].count);else return E_ARC;
      if (strcmp(e[i].type,"ARCTG")==0)e[i].count=atan(e[i+1].count);
      if (strcmp(e[i].type,"ARCCTG")==0)e[i].count=3.14159265358979f/2-atan(e[i+1].count );
      if (strcmp(e[i].type,"EXP")==0)e[i].count=exp(e[i+1].count);

      if (strcmp(e[i].type,"-LN")==0)if (e[i+1].count>0)e[i].count=-log(e[i+1].count);else return E_LN;
      if (strcmp(e[i].type,"-LG")==0)if (e[i+1].count>0)e[i].count=-log10(e[i+1].count);else return E_LG;
      if (strcmp(e[i].type,"-SIN")==0)e[i].count=-sin(e[i+1].count);
      if (strcmp(e[i].type,"-COS")==0)e[i].count=-cos(e[i+1].count);
      if (strcmp(e[i].type,"-TG")==0)if (cos(e[i+1].count)!=0)e[i].count=-tan(e[i+1].count);else return E_TG;
      if (strcmp(e[i].type,"-CTG")==0)if (sin(e[i+1].count)!=0)e[i].count=-1/tan(e[i+1].count);else return E_CTG;
      if (strcmp(e[i].type,"-ARCSIN")==0)if((e[i+1].count>=-1)&&(e[i+1].count<=1))e[i].c ount=-asin(e[i+1].count);else return E_ARC;
      if (strcmp(e[i].type,"-ARCCOS")==0)if((e[i+1].count>=-1)&&(e[i+1].count<=1))e[i].c ount=-acos(e[i+1].count);else return E_ARC;
      if (strcmp(e[i].type,"-ARCTG")==0)e[i].count=-atan(e[i+1].count);
      if (strcmp(e[i].type,"-ARCCTG")==0)e[i].count=-3.14159265358979f/2+atan(e[i+1].cou nt);
      if (strcmp(e[i].type,"-EXP")==0)e[i].count=-exp(e[i+1].count);

      e[i].type=strdup("COUNT");
      len=Delete(e,i+1,len);
      l--;
     }
    else
     i++;


 i=f;
 while (i<l)
    if (e[i].oper=='^')
     {
      e[i].oper=e[i+1].oper;
      if (e[i].count>0)
      e[i].count=exp(log(e[i].count)*e[i+1].count);
      else
      if (ceil(e[i+1].count)==e[i+1].count)e[i].count=step(e[i].count,(long)e[i+1].count );
      else return E_STEP;
      len=Delete(e,i+1,len);
      l--;
     }
    else
     i++;


 i=f;
 while (i<l)
    if (e[i].oper=='*')
     {
      e[i].oper=e[i+1].oper;
      e[i].count*=e[i+1].count;
      len=Delete(e,i+1,len);
      l--;
     }
    else
     if (e[i].oper=='/')
     {
      e[i].oper=e[i+1].oper;
      if (e[i+1].count!=0)
      e[i].count/=e[i+1].count;else return E_ZERO;
      len=Delete(e,i+1,len);
      l--;
     } else

     i++;




 i=f;
 while (i<l)
    if (e[i].oper=='+')
     {
      e[i].oper=e[i+1].oper;
      e[i].count+=e[i+1].count;
      len=Delete(e,i+1,len);
      l--;
     }
    else
     if (e[i].oper=='-')
      {
       e[i].oper=e[i+1].oper;
       e[i].count-=e[i+1].count;
       len=Delete(e,i+1,len);
       l--;
      }
     else
       i++;
e[f].oper=e[f+1].oper;
if (e[f-1].type[0]=='|')
if (e[l].type[0]!=e[f-1].type[0])
return E_ABS
else e[f].count=fabs(e[f].count);
len=Delete(e,f-1,len);
len=Delete(e,l-1,len);

return len;
};



float Vir(float x)
{
SetX(x);
int l=Num;

while (l>1)l=fx(&t[0],l);
if (l<1) Error=TRUE; else Error=FALSE;
if (Error) {
return 0.0f; };
return t[0].count;
};




boolean Count(char c)
{
if (((c<='9')&&(c>='0'))||(c=='.')||(c=='-'))return TRUE;
return FALSE;
};

boolean znak(char c)
{
if ((c=='|')||(c=='=')||(c=='(')||(c==')')||(c=='^')||(c=='+')||(c=='-')||(c==' /') ||(c=='*'))return TRUE;
return FALSE;
};







BOOL FX(char*in,char*out)
{

char* ch="<>YEXPEPILGLNSINCOSARCSINARCCOSTGCTGARCTGARCCTG()1234567890+-*/^=.X|" ;
char tk[256];
DWORD i;
int len=0;
for (i=0;i<256;i++)
if (!strchr(ch,(char)i))
{
tk[len]=(char)i;
len++;
};
tk[len]=0;

len=0;
in=strupr(in);
char buf[1000];
buf[0]=0;
BOOL sk=FALSE;

char*tok;
tok=strtok(in,tk);
while (tok){strcat(buf,tok);tok=strtok(NULL,tk);};
strcpy(in,buf);

for (i=0;i<strlen(in);i++)
{
if (znak(in[i]))
{
buf[len]=' ';
buf[len+1]=in[i];
buf[len+2]=' ';
len+=3;
if ((sk)&&((in[i]=='-')||(in[i]=='+')))len--;
if ((in[i-2]!=')')&&(znak(in[i-2]))&&(in[i-1]=='|')&&((in[i]=='-')||(in[i]=='+' ))) len--;
}
else
{
buf[len]=in[i];
len++;
};
if ((in[i]!='(')&&(in[i]!=' '))sk=FALSE;
if (in[i]=='(')sk=TRUE;
};
buf[len]=0;
if (out)
strcpy(out,buf);

tok=strtok(buf,tk);

i=0;
while (tok)
{

if (((strlen(tok)>1)&&(Count(tok[1])))||((strlen(tok)==1)&&(Count(tok[0]))))
{
sscanf(tok,"%f",&e[i].count);
e[i].type=strdup("COUNT");
tok=strtok(NULL,tk);

while ((tok[0]==')')||(tok[0]=='|'))
{
e[i].oper='=';
i++;
e[i].type=strdup(tok);
tok=strtok(NULL,tk);
e[i].count=0.0f;
};

e[i].oper=tok[0];
i++;

}
else

if (strcmp(tok,"E")==0)
{
e[i].count=2.71828182845904f;
e[i].type=strdup("COUNT");
tok=strtok(NULL,tk);

while ((tok[0]==')')||(tok[0]=='|'))
{
e[i].oper='=';
i++;
e[i].type=strdup(tok);
tok=strtok(NULL,tk);
e[i].count=0.0f;
};

e[i].oper=tok[0];
i++;

}
else
if (strcmp(tok,"-E")==0)
{
e[i].count=-2.71828182845904f;
e[i].type=strdup("COUNT");
tok=strtok(NULL,tk);
while ((tok[0]==')')||(tok[0]=='|'))
{
e[i].oper='=';
i++;
e[i].type=strdup(tok);

tok=strtok(NULL,tk);
e[i].count=0.0f;
};

e[i].oper=tok[0];
i++;

}
else

if (strcmp(tok,"PI")==0)
{
e[i].count=3.14159265358979f;
e[i].type=strdup("COUNT");
tok=strtok(NULL,tk);
while ((tok[0]==')')||(tok[0]=='|'))
{
e[i].oper='=';
i++;
e[i].type=strdup(tok);

tok=strtok(NULL,tk);
e[i].count=0.0f;
};

e[i].oper=tok[0];
i++;
}
else
if (strcmp(tok,"-PI")==0)
{
e[i].count=-3.14159265358979f;
e[i].type=strdup("COUNT");
tok=strtok(NULL,tk);
while ((tok[0]==')')||(tok[0]=='|'))
{
e[i].oper='=';
i++;
e[i].type=strdup(tok);
tok=strtok(NULL,tk);
e[i].count=0.0f;
};

e[i].oper=tok[0];
i++;
}
else

if ((tok[0]!='X')&&(strcmp(tok,"-X"))&&(tok[0]!='Y')&&(strcmp(tok,"-Y")))
{
e[i].count=0.0f;
e[i].oper='&';
e[i].type=strdup(tok);
i++;
}
else
{
e[i].count=0.0f;
e[i].type=strdup(tok);
tok=strtok(NULL,tk);
while ((tok[0]==')')||(tok[0]=='|'))
{
e[i].oper='=';
i++;
e[i].type=strdup(tok);;
tok=strtok(NULL,tk);
e[i].count=0.0f;
};

e[i].oper=tok[0];
i++;
};
tok=strtok(NULL,tk);
};

len=i;




Num=len;

return TRUE;
};


BOOL FX_OK()
{
int m1=0,m2=0,s1=0,s2=0,i;

for (i=0;i<Num;i++)
{
if ((e[i].oper!='+')&&
 (e[i].oper!='-')&&
 (e[i].oper!='^')&&
 (e[i].oper!='*')&&
 (e[i].oper!='/')&&
 (e[i].oper!='=')&&
 (e[i].oper!='&'))return FALSE;

if (e[i].oper=='&')
{
if (
(strcmp(e[i].type,"LN"))&&
(strcmp(e[i].type,"LG"))&&
(strcmp(e[i].type,"-LN"))&&
(strcmp(e[i].type,"-LG"))&&
(strcmp(e[i].type,"SIN"))&&
(strcmp(e[i].type,"-SIN"))&&
(strcmp(e[i].type,"COS"))&&
(strcmp(e[i].type,"-COS"))&&
(strcmp(e[i].type,"TG"))&&
(strcmp(e[i].type,"-TG"))&&
(strcmp(e[i].type,"CTG"))&&
(strcmp(e[i].type,"-CTG"))&&
(strcmp(e[i].type,"ARCSIN"))&&
(strcmp(e[i].type,"ARCCOS"))&&
(strcmp(e[i].type,"ARCTG"))&&
(strcmp(e[i].type,"ARCCTG"))&&
(strcmp(e[i].type,"EXP"))&&
(strcmp(e[i].type,"-ARCSIN"))&&
(strcmp(e[i].type,"-ARCCOS"))&&
(strcmp(e[i].type,"-ARCTG"))&&
(strcmp(e[i].type,"-ARCCTG"))&&
(strcmp(e[i].type,"-EXP"))&&
(strcmp(e[i].type,"("))&&
(strcmp(e[i].type,"|")))return FALSE;
};

if (strcmp(e[i].type,"(")==0)s1++;
if (strcmp(e[i].type,")")==0)s2++;

if ((strcmp(e[i].type,"|")==0)&&(e[i].oper=='&'))m1++;
if ((strcmp(e[i].type,"|")==0)&&(e[i].oper!='&'))m2++;

};
if ((m1!=m2)||(s1!=s2))return FALSE;

return TRUE;
};
=== Cut ===
Всего хорошего!
>>> С уважением, Petr!!!
--- GoldED/W32 3.0.1-asa9 SR3
 * Origin:  (2:5025/54.26)