forked from metin2/server
932 lines
17 KiB
C++
932 lines
17 KiB
C++
#include <string>
|
|
#include "Poly.h"
|
|
#include "Constants.h"
|
|
#include <cmath>
|
|
#include <cctype>
|
|
#include <cstdlib>
|
|
|
|
using namespace std;
|
|
|
|
double _random()
|
|
{
|
|
#ifndef __WIN32__
|
|
return random() / (2147483648.0);
|
|
#else
|
|
return rand() / (2147483648.0);
|
|
#endif
|
|
}
|
|
|
|
int CPoly::my_irandom(double start, double end)
|
|
{
|
|
// Make range as inclusive-exclusive
|
|
int is = int(start + 0.5);
|
|
int ie = int(end - start + 0.5) + 1;
|
|
|
|
return int(_random() * ie + is);
|
|
}
|
|
|
|
double CPoly::my_frandom(double start, double end)
|
|
{
|
|
return _random() * (end - start) + start;
|
|
}
|
|
|
|
CPoly::CPoly()
|
|
: iToken(0), iNumToken(0), iLookAhead(0), iErrorPos(0), ErrorOccur(true),
|
|
uiLookPos(0), STSize(0)
|
|
{
|
|
lSymbol.clear();
|
|
lSymbol.reserve(50);
|
|
|
|
init();
|
|
}
|
|
|
|
CPoly::~CPoly()
|
|
{
|
|
Clear();
|
|
}
|
|
|
|
void CPoly::SetStr(const string & str)
|
|
{
|
|
strData = str;
|
|
}
|
|
|
|
double CPoly::Eval()
|
|
{
|
|
int stNow;
|
|
double save[MAXSTACK],t;
|
|
int iSp=0;
|
|
if (ErrorOccur)
|
|
{
|
|
/*THROW(new CEvalException("Evaluate Error"));*/
|
|
return 0;
|
|
}
|
|
|
|
//TEST
|
|
//list<int>::iterator pos = tokenBase.begin();
|
|
//list<double>::iterator posn = numBase.begin();
|
|
vector<int>::iterator pos = tokenBase.begin();
|
|
vector<double>::iterator posn = numBase.begin();
|
|
while (pos != tokenBase.end())
|
|
{
|
|
|
|
stNow=*pos;
|
|
++pos;
|
|
switch (stNow)
|
|
{
|
|
case NUM:
|
|
save[iSp++]=*posn++; break;
|
|
case ID:
|
|
save[iSp++]=
|
|
lSymbol[ *pos ]->dVal;
|
|
pos++;
|
|
break;
|
|
//case '+':
|
|
case PLU:
|
|
iSp--;
|
|
save[iSp-1]+=save[iSp]; break;
|
|
//case '-':
|
|
case MIN:
|
|
iSp--;
|
|
save[iSp-1]-=save[iSp]; break;
|
|
//case '*':
|
|
case MUL:
|
|
iSp--;
|
|
save[iSp-1]*=save[iSp]; break;
|
|
//case '%':
|
|
case MOD:
|
|
iSp--;
|
|
if (save[iSp]==0)
|
|
{
|
|
//THROW(new CEvalException("Divide by 0"));
|
|
return 0;
|
|
}
|
|
save[iSp-1]=fmod(save[iSp-1],save[iSp]); break;
|
|
//case '/':
|
|
case DIV:
|
|
iSp--;
|
|
if (save[iSp]==0)
|
|
{
|
|
//THROW(new CEvalException("Divide by 0"));
|
|
return 0;
|
|
}
|
|
save[iSp-1]/=save[iSp]; break;
|
|
//case '^':
|
|
case POW:
|
|
iSp--;
|
|
save[iSp-1]=pow(save[iSp-1],save[iSp]); break;
|
|
case ROOT:
|
|
if (save[iSp-1]<0)
|
|
{
|
|
//THROW(new CEvalException("Negative in root"));
|
|
return 0;
|
|
}
|
|
save[iSp-1]=sqrt(save[iSp-1]); break;
|
|
case COS:
|
|
save[iSp-1]=cos(save[iSp-1]); break;
|
|
case SIN:
|
|
save[iSp-1]=sin(save[iSp-1]); break;
|
|
case SIGN:
|
|
if (save[iSp-1] == 0.0) save[iSp-1] = 0.0;
|
|
else if (save[iSp-1] < 0.0) save[iSp-1] = -1.0;
|
|
else save[iSp-1] = 1.0f;
|
|
break;
|
|
case TAN:
|
|
if (!(t=cos(save[iSp-1])))
|
|
{
|
|
//THROW (new CEvalException("Divide by 0"));
|
|
return 0;
|
|
}
|
|
save[iSp-1]=tan(save[iSp-1]); break;
|
|
case CSC:
|
|
if (!(t=sin(save[iSp-1])))
|
|
{
|
|
//THROW(new CEvalException("Divide by 0"));
|
|
return 0;
|
|
}
|
|
save[iSp-1]=1/t; break;
|
|
case SEC:
|
|
if (!(t=cos(save[iSp-1])))
|
|
{
|
|
//THROW(new CEvalException("Divide by 0"));
|
|
return 0;
|
|
}
|
|
save[iSp-1]=1/t; break;
|
|
case COT:
|
|
if (!(t=sin(save[iSp-1])))
|
|
{
|
|
//THROW(new CEvalException("Divide by 0"));
|
|
return 0;
|
|
}
|
|
save[iSp-1]=cos(save[iSp-1])/t; break;
|
|
case LN:
|
|
if (save[iSp-1]<=0)
|
|
{
|
|
//THROW( new CEvalException("Call Log with minus number"));
|
|
return 0;
|
|
}
|
|
save[iSp-1]=log(save[iSp-1]); break;
|
|
case LOG10:
|
|
if (save[iSp-1]<=0)
|
|
{
|
|
//THROW( new CEvalException("Call Log with minus number"));
|
|
return 0;
|
|
}
|
|
save[iSp-1]=log10(save[iSp-1]); break;
|
|
case LOG:
|
|
if (save[iSp-1]<=0)
|
|
{
|
|
//THROW( new CEvalException("Call Log with minus number"));
|
|
return 0;
|
|
}
|
|
if (save[iSp-2]<=0 || save[iSp-2]==1)
|
|
{
|
|
//THROW( new CEvalException("Call Log with minus number"));
|
|
return 0;
|
|
}
|
|
|
|
save[iSp-2]=log(save[iSp-1])/log(save[iSp-2]);
|
|
iSp--;
|
|
break;
|
|
case ABS: save[iSp-1]=fabs(save[iSp-1]); break;
|
|
case FLOOR: save[iSp-1]=floor(save[iSp-1]); break;
|
|
case IRAND:
|
|
save[iSp-2]=my_irandom(save[iSp-2],save[iSp-1]);
|
|
iSp--;
|
|
break;
|
|
case FRAND:
|
|
save[iSp-2]=my_frandom(save[iSp-2],save[iSp-1]);
|
|
iSp--;
|
|
break;
|
|
case MINF:
|
|
save[iSp-2]=(save[iSp-2]<save[iSp-1])?save[iSp-2]:save[iSp-1];
|
|
iSp--;
|
|
break;
|
|
case MAXF:
|
|
save[iSp-2]=(save[iSp-2]>save[iSp-1])?save[iSp-2]:save[iSp-1];
|
|
iSp--;
|
|
break;
|
|
/*case MOD:
|
|
save[iSp-2]=fmod(save[iSp-2],save[iSp-1]);
|
|
iSp--;
|
|
break;*/
|
|
default:
|
|
return 0;
|
|
//THROW(new CEvalException("Token Error"));
|
|
}
|
|
}
|
|
return save[iSp-1];
|
|
}
|
|
|
|
int CPoly::Analyze(const char * pszStr)
|
|
{
|
|
if (pszStr)
|
|
SetStr(pszStr);
|
|
|
|
if (0 == strData.length())
|
|
return true;
|
|
|
|
//DisposeList();
|
|
ErrorOccur = false;
|
|
uiLookPos = 0;
|
|
iLookAhead = lexan();
|
|
|
|
expr();
|
|
|
|
if (tokenBase.empty())
|
|
{
|
|
//THROW(new CParseException("No Data"));
|
|
return false;
|
|
}
|
|
|
|
return !ErrorOccur;
|
|
}
|
|
|
|
void CPoly::Clear()
|
|
{
|
|
int i;
|
|
//while (!tokenBase.IsEmpty()) listBase.RemoveTail();
|
|
//while (!numBase.IsEmpty()) numBase.RemoveTail();
|
|
tokenBase.clear();
|
|
numBase.clear();
|
|
|
|
for (i = 0;i < STSize; ++i)
|
|
{
|
|
if (lSymbol[i]) delete lSymbol[i];
|
|
lSymbol[i]=NULL;
|
|
}
|
|
//lSymbol.FreeExtra();
|
|
lSymbol.clear();
|
|
SymbolIndex.clear();
|
|
STSize=0;
|
|
}
|
|
|
|
void CPoly::expr()
|
|
{
|
|
int t;
|
|
|
|
switch (iLookAhead)
|
|
{
|
|
case '+':
|
|
case '-':
|
|
uiLookPos--;
|
|
iLookAhead = NUM;
|
|
iNumToken = iToken = 0;
|
|
|
|
}
|
|
|
|
term();
|
|
|
|
while (!ErrorOccur)
|
|
{
|
|
switch (iLookAhead)
|
|
{
|
|
case '+':
|
|
case '-':
|
|
t=iLookAhead;
|
|
match(t);
|
|
term();
|
|
emit(t,NONE);
|
|
continue;
|
|
case EOS: case ')': case ',': return;
|
|
default:
|
|
error();
|
|
//THROW( new CParseException("Error Parsing"));
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CPoly::error()
|
|
{
|
|
iErrorPos=uiLookPos;
|
|
ErrorOccur=true;
|
|
}
|
|
|
|
int CPoly::lexan()
|
|
{
|
|
int t;
|
|
double tt;
|
|
|
|
while (uiLookPos < strData.size())
|
|
{
|
|
if (strData[uiLookPos] == ' ' || strData[uiLookPos] == '\t')
|
|
;
|
|
else if (isdigit(strData[uiLookPos]))
|
|
{
|
|
t = 0;
|
|
for (;uiLookPos<strData.size();uiLookPos++)
|
|
{
|
|
if (isdigit(strData[uiLookPos]))
|
|
t = t * 10 + strData[uiLookPos] - '0';
|
|
else
|
|
break;
|
|
}
|
|
iToken=t;
|
|
tt=0.1;
|
|
iNumToken=0;
|
|
if (uiLookPos<strData.size() && strData[uiLookPos]=='.')
|
|
{
|
|
uiLookPos++;
|
|
for (;uiLookPos<strData.size();uiLookPos++,tt*=0.1)
|
|
{
|
|
if (isdigit(strData[uiLookPos]))
|
|
iNumToken+=tt*(strData[uiLookPos]-'0');
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
iNumToken+=iToken;
|
|
return NUM;
|
|
}
|
|
else if (isalpha(strData[uiLookPos]))
|
|
{
|
|
string localSymbol("");
|
|
while (uiLookPos<strData.size() && isalpha(strData[uiLookPos]))
|
|
{
|
|
localSymbol+=strData[uiLookPos];
|
|
uiLookPos++;
|
|
}
|
|
iToken= find(localSymbol);
|
|
if (iToken==-1)
|
|
{
|
|
iToken=insert(localSymbol,ID);
|
|
}
|
|
return lSymbol[(/*FindIndex*/(iToken))]->token;
|
|
}
|
|
else
|
|
{
|
|
iToken=0;
|
|
return strData[uiLookPos++];
|
|
}
|
|
uiLookPos++;
|
|
}
|
|
return EOS;
|
|
}
|
|
|
|
void CPoly::term()
|
|
{
|
|
int t;
|
|
factor();
|
|
while (!ErrorOccur)
|
|
{
|
|
switch (iLookAhead)
|
|
{
|
|
case '*':
|
|
case '/':
|
|
case '%':
|
|
t=iLookAhead;
|
|
match(t);
|
|
factor();
|
|
emit(t,NONE);
|
|
continue;
|
|
default:
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CPoly::factor()
|
|
{
|
|
int t;
|
|
expo();
|
|
while (!ErrorOccur)
|
|
{
|
|
switch (iLookAhead)
|
|
{
|
|
case '^':
|
|
t=iLookAhead;
|
|
match(t);
|
|
expo();
|
|
emit(t,NONE);
|
|
continue;
|
|
default:
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CPoly::expo()
|
|
{
|
|
int t;
|
|
switch (iLookAhead)
|
|
{
|
|
case '(':
|
|
match('('); expr(); match(')'); break;
|
|
case NUM:
|
|
emit(NUM, iToken); match(NUM); break;
|
|
case ID:
|
|
emit(ID,(int)/*FindIndex*/(iToken)); match(ID); break;
|
|
case ROOT:
|
|
case SIN:
|
|
case COT:
|
|
case TAN:
|
|
case CSC:
|
|
case SEC:
|
|
case LN:
|
|
case LOG10:
|
|
case COS:
|
|
case ABS:
|
|
case FLOOR:
|
|
case SIGN:
|
|
t=iLookAhead;
|
|
match(iLookAhead); match('('); expr(); match(')'); emit(t,iToken);
|
|
break;
|
|
|
|
case LOG:
|
|
case MINF:
|
|
case MAXF:
|
|
case IRAND:
|
|
case FRAND:
|
|
case MOD:
|
|
t=iLookAhead;
|
|
match(iLookAhead); match('('); expr(); match(','); expr(); match(')'); emit(t,iToken);
|
|
break;
|
|
case EOS:
|
|
break;
|
|
default:
|
|
error();
|
|
//THROW( new CParseException("Error Parsing"));
|
|
}
|
|
}
|
|
|
|
void CPoly::match(int t)
|
|
{
|
|
if (iLookAhead==t) iLookAhead=lexan(); else error();
|
|
}
|
|
|
|
void CPoly::emit(int t, int tval)
|
|
{
|
|
switch (t)
|
|
{
|
|
case '+':
|
|
tokenBase.push_back(PLU);
|
|
break;
|
|
case '-':
|
|
tokenBase.push_back(MIN);
|
|
break;
|
|
case '*':
|
|
tokenBase.push_back(MUL);
|
|
break;
|
|
case '/':
|
|
tokenBase.push_back(DIV);
|
|
break;
|
|
case '%':
|
|
tokenBase.push_back(MOD);
|
|
break;
|
|
case '^':
|
|
tokenBase.push_back(POW);
|
|
break;
|
|
case ROOT:
|
|
case SIN:
|
|
case TAN:
|
|
case COT:
|
|
case COS:
|
|
case CSC:
|
|
case SEC:
|
|
case LOG:
|
|
case LN:
|
|
case LOG10:
|
|
case ABS:
|
|
case MINF:
|
|
case MAXF:
|
|
case IRAND:
|
|
case FRAND:
|
|
case MOD:
|
|
case FLOOR:
|
|
case SIGN:
|
|
tokenBase.push_back(t);
|
|
break;
|
|
case NUM:
|
|
tokenBase.push_back(t);
|
|
numBase.push_back(iNumToken);
|
|
break;
|
|
case ID:
|
|
tokenBase.push_back(t);
|
|
tokenBase.push_back(tval); break;
|
|
default:
|
|
error();
|
|
Clear();
|
|
//THROW( new CParseException("Error Parsing"));
|
|
return;
|
|
}
|
|
}
|
|
|
|
int CPoly::find(const string & s)
|
|
{
|
|
int l, m, r;
|
|
|
|
l = 0;
|
|
r = STSize - 1;
|
|
|
|
while (l <= r)
|
|
{
|
|
m = (l + r) >> 1;
|
|
|
|
if (lSymbol[SymbolIndex[m]]->strlex == s)
|
|
return SymbolIndex[m];
|
|
else if (lSymbol[SymbolIndex[m]]->strlex < s)
|
|
l = m + 1;
|
|
else
|
|
r = m - 1;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
int CPoly::insert(const string & s, int tok)
|
|
{
|
|
int i;
|
|
bool bAdded=false;
|
|
//s.MakeLower();
|
|
//transform(s.begin(),s.end(),s.begin(),std::tolower);
|
|
//lSymbol.SetAtGrow(STSize,new CSymTable(tok,s));
|
|
lSymbol.push_back(new CSymTable(tok,s));
|
|
for (i=0;i<STSize;i++)
|
|
{
|
|
if (s<lSymbol[SymbolIndex[i]]->strlex)
|
|
{
|
|
SymbolIndex.insert(SymbolIndex.begin()+i,STSize);
|
|
bAdded=true;
|
|
break;
|
|
}
|
|
}
|
|
if (!bAdded)
|
|
{
|
|
//SymbolIndex.SetAtGrow(STSize,STSize);
|
|
SymbolIndex.push_back(STSize);
|
|
}
|
|
STSize++;
|
|
return STSize-1;
|
|
}
|
|
|
|
int CPoly::SetVar(const string & strName, double dVar)
|
|
{
|
|
//transform(strName.begin(),strName.end(),s.begin(),std::tolower);
|
|
if (ErrorOccur) return false;
|
|
int index = find(strName);
|
|
if (index == -1) return false;
|
|
CSymTable * stVar = lSymbol[(/*FindIndex*/(index))];
|
|
stVar->dVal = dVar;
|
|
return true;
|
|
}
|
|
|
|
double CPoly::GetVar(const std::string & strName)
|
|
{
|
|
if (ErrorOccur) return false;
|
|
int index = find(strName);
|
|
if (index == -1) return false;
|
|
CSymTable * stVar = lSymbol[(/*FindIndex*/(index))];
|
|
if(!stVar)
|
|
return -1;
|
|
return stVar->dVal;
|
|
}
|
|
|
|
void CPoly::init()
|
|
{
|
|
insert("min",MINF);
|
|
insert("max",MAXF);
|
|
insert("number", IRAND);
|
|
insert("irandom", IRAND);
|
|
insert("irand", IRAND);
|
|
insert("frandom",FRAND);
|
|
insert("frand",FRAND);
|
|
insert("rt",ROOT);
|
|
insert("sqrt",ROOT);
|
|
insert("cos",COS);
|
|
insert("sin",SIN);
|
|
insert("tan",TAN);
|
|
insert("cot",COT);
|
|
insert("csc",CSC);
|
|
insert("cosec",COSEC);
|
|
insert("sec",SEC);
|
|
insert("pi",PI);
|
|
SetVar("pi",3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117068);
|
|
insert("e",EXP);
|
|
SetVar("e",2.718281828459045235360287471352662497757247093699959574966967627724076630353547594571382178525166427);
|
|
insert("log",LOG);
|
|
insert("ln",LN);
|
|
insert("log10",LOG10);
|
|
insert("abs",ABS);
|
|
insert("mod",MOD);
|
|
insert("floor", FLOOR);
|
|
insert("sign",SIGN);
|
|
}
|
|
|
|
/*
|
|
void CPoly::AddSymTable(CPtrList* ns)
|
|
{
|
|
int i, len = ns->GetCount();
|
|
CSymTable* a, *b;
|
|
int index;
|
|
POSITION pos;
|
|
pos = ns->GetHeadPosition();
|
|
for (i=0;i<len;i++)
|
|
{
|
|
a = ((CSymTable*)ns->GetNext(pos));
|
|
if ((index=find(a->strlex))==-1)
|
|
{
|
|
lSymbol[insert(a->strlex,a->token)]->dVal = a->dVal;
|
|
//lSymbol.SetAtGrow(STSize,b);
|
|
//STSize++;
|
|
}
|
|
else
|
|
{
|
|
(lSymbol.GetAt(FindIndex(index)))->dVal = a->dVal;
|
|
}
|
|
|
|
}
|
|
}
|
|
*/
|
|
|
|
/*
|
|
void CPoly::Diff(CString& str)
|
|
{
|
|
int stNow, cc;
|
|
int i;
|
|
CString* mstr,*bstr;
|
|
if (ErrorOccur) //THROW(new CEvalException("Diff Error"));
|
|
return;
|
|
mstr = new CString[tokenBase.GetCount()];
|
|
bstr = new CString[tokenBase.GetCount()];
|
|
POSITION pos = tokenBase.GetHeadPosition();
|
|
POSITION posn = numBase.GetHeadPosition();
|
|
cc=0;
|
|
while (pos != NULL)
|
|
{
|
|
|
|
stNow=tokenBase.GetNext(pos);
|
|
switch (stNow)
|
|
{
|
|
case NUM:
|
|
//save[iSp++]=numBase.GetNext(posn);
|
|
mstr[cc]="0";bstr[cc].Format("%f",numBase.GetNext(posn));
|
|
for (i=bstr[cc].GetLength()-1;i>=0;i--)
|
|
if (bstr[cc][i] != '0')
|
|
break;
|
|
if (i>0)
|
|
bstr[cc]=bstr[cc].Left(i+1);
|
|
i=bstr[cc].GetLength()-1;
|
|
if (bstr[cc][i]=='.')
|
|
{
|
|
bstr[cc]=bstr[cc].Left(i);
|
|
}
|
|
cc++; break;
|
|
|
|
case ID:
|
|
////save[iSp++]=
|
|
//lSymbol.GetAt(
|
|
//lSymbol.FindIndex(
|
|
//(POSITION )tokenBase.GetNext(pos)
|
|
// )
|
|
//)->dVal;
|
|
bstr[cc] = lSymbol.GetAt(tokenBase.GetNext(pos))->strlex;
|
|
if (bstr[cc] != "x") mstr[cc]="0";
|
|
else mstr[cc] = "1";
|
|
cc++;
|
|
break;
|
|
case '+':
|
|
cc--;
|
|
if (bstr[cc-1]=="0")
|
|
{
|
|
if (bstr[cc]=="0")
|
|
bstr[cc-1]="0";
|
|
else
|
|
bstr[cc-1]="("+bstr[cc]+")";
|
|
}
|
|
else if (bstr[cc]=="0")
|
|
{
|
|
bstr[cc-1]="("+bstr[cc-1]+")";
|
|
}
|
|
else
|
|
bstr[cc-1]="("+bstr[cc-1]+"+"+bstr[cc]+")";
|
|
bstr[cc]="";
|
|
|
|
if (mstr[cc-1]=="0")
|
|
{
|
|
if (mstr[cc]=="0")
|
|
mstr[cc-1]="0";
|
|
else
|
|
mstr[cc-1]="("+mstr[cc]+")";
|
|
}
|
|
else if (mstr[cc]=="0")
|
|
{
|
|
mstr[cc-1]="("+mstr[cc-1]+")";
|
|
}
|
|
else
|
|
mstr[cc-1]="("+mstr[cc-1]+"+"+mstr[cc]+")";
|
|
mstr[cc]="";
|
|
|
|
break;
|
|
case '-':
|
|
cc--;
|
|
if (bstr[cc-1]=="0")
|
|
{
|
|
if (bstr[cc]=="0")
|
|
bstr[cc-1]="0";
|
|
else
|
|
bstr[cc-1]="(-"+bstr[cc]+")";
|
|
}
|
|
else if (bstr[cc]=="0")
|
|
{
|
|
bstr[cc-1]="("+bstr[cc-1]+")";
|
|
}
|
|
else
|
|
bstr[cc-1]="("+bstr[cc-1]+"-"+bstr[cc]+")";
|
|
bstr[cc]="";
|
|
|
|
if (mstr[cc-1]=="0")
|
|
{
|
|
if (mstr[cc]=="0")
|
|
mstr[cc-1]="0";
|
|
else
|
|
mstr[cc-1]="(-"+mstr[cc]+")";
|
|
}
|
|
else if (mstr[cc]=="0")
|
|
{
|
|
mstr[cc-1]="("+mstr[cc-1]+")";
|
|
}
|
|
else
|
|
mstr[cc-1]="("+mstr[cc-1]+"-"+mstr[cc]+")";
|
|
mstr[cc]="";
|
|
|
|
break;
|
|
case '*':
|
|
cc--;
|
|
if (mstr[cc-1]=="0" || bstr[cc]=="0")
|
|
{
|
|
if (mstr[cc]=="0" || bstr[cc-1]=="0")
|
|
{
|
|
mstr[cc-1]="0";
|
|
}
|
|
else
|
|
{
|
|
mstr[cc-1]="("+ mstr[cc] + "*" +bstr[cc-1] +")";
|
|
}
|
|
}
|
|
else if (mstr[cc]=="0" || bstr[cc-1]=="0")
|
|
{
|
|
mstr[cc-1] = "("+mstr[cc-1] + "*" + bstr[cc] + ")";
|
|
}
|
|
else
|
|
mstr[cc-1] = "(("+mstr[cc-1] + "*" + bstr[cc] + ")+(" +mstr[cc] + "*" +bstr[cc-1] +"))";
|
|
|
|
if (bstr[cc-1]=="0" || bstr[cc]=="0")
|
|
{
|
|
bstr[cc-1]="0";
|
|
}
|
|
else
|
|
bstr[cc-1]="("+bstr[cc-1]+"*"+bstr[cc]+")";
|
|
mstr[cc]=""; bstr[cc]="";
|
|
break;
|
|
case '/':
|
|
cc--;
|
|
if (bstr[cc]=="0") THROW(new CEvalException("Divide by Zero"));
|
|
if (mstr[cc-1]=="0"||bstr[cc]=="0")
|
|
{
|
|
if (mstr[cc]=="0" || bstr[cc-1]=="0")
|
|
{
|
|
mstr[cc-1]="0";
|
|
}
|
|
else
|
|
mstr[cc-1]="((-" +mstr[cc]+"*"+bstr[cc-1]+ ")/("+bstr[cc]+")^2)";
|
|
}
|
|
else if (mstr[cc]=="0"||bstr[cc-1]=="0")
|
|
{
|
|
mstr[cc-1]="((" +mstr[cc-1]+"*"+bstr[cc] + ")/("+bstr[cc]+")^2)";
|
|
}
|
|
else
|
|
mstr[cc-1]="((" +mstr[cc-1]+"*"+bstr[cc]+ "-" +mstr[cc]+"*"+bstr[cc-1]+ ")/("+bstr[cc]+")^2)";
|
|
if (bstr[cc-1]=="0")
|
|
bstr[cc-1]="0";
|
|
else
|
|
bstr[cc-1]="("+bstr[cc-1]+")/("+bstr[cc]+")";
|
|
break;
|
|
case '^':
|
|
cc--;
|
|
if (mstr[cc-1]=="0")
|
|
{
|
|
if (mstr[cc]=="0")
|
|
{
|
|
mstr[cc-1]="0";
|
|
mstr[cc]="";
|
|
}
|
|
else
|
|
{
|
|
mstr[cc-1]="ln("+bstr[cc-1]+")*("+bstr[cc-1]+")^("+bstr[cc]+")*("+mstr[cc]+")";
|
|
mstr[cc]="";
|
|
}
|
|
}
|
|
else if (mstr[cc]=="0")
|
|
{
|
|
mstr[cc-1]="("+bstr[cc]+")*("+bstr[cc-1]+")^("+bstr[cc]+"-1)*("+mstr[cc-1]+")";
|
|
mstr[cc]="";
|
|
}
|
|
else
|
|
{
|
|
mstr[cc-1]="(ln("+bstr[cc-1]+")*("+bstr[cc-1]+")^("+bstr[cc]+")*("+mstr[cc]+")+("+bstr[cc]+")*("+bstr[cc-1]+")^("+bstr[cc]+"-1)*("+mstr[cc-1]+"))";
|
|
mstr[cc]="";
|
|
|
|
}
|
|
|
|
if (bstr[cc-1]=="0")
|
|
{
|
|
bstr[cc-1]="0";
|
|
}
|
|
else if (bstr[cc-1]=="1")
|
|
{
|
|
bstr[cc-1]="1";
|
|
}
|
|
else if (bstr[cc]=="1")
|
|
{
|
|
|
|
}
|
|
else if (bstr[cc]=="0")
|
|
{
|
|
bstr[cc-1]="0";
|
|
}
|
|
else
|
|
bstr[cc-1]="("+bstr[cc-1]+")^("+bstr[cc]+")";
|
|
|
|
bstr[cc]="";
|
|
break;
|
|
case ROOT:
|
|
cc--;
|
|
if (mstr[cc]=="0")
|
|
mstr[cc]="0";
|
|
else
|
|
mstr[cc]="("+mstr[cc]+"/2/rt("+bstr[cc]+"))";
|
|
bstr[cc]="rt("+bstr[cc] +")";
|
|
cc++;
|
|
break;
|
|
case COS:
|
|
cc--;
|
|
mstr[cc]="(-"+mstr[cc]+"*sin("+bstr[cc]+"))";
|
|
bstr[cc]="cos("+bstr[cc]+")";
|
|
cc++;
|
|
break;
|
|
case SIN:
|
|
cc--;
|
|
mstr[cc]="("+mstr[cc]+"*cos("+bstr[cc]+"))";
|
|
bstr[cc]="sin("+bstr[cc]+")";
|
|
cc++;
|
|
break;
|
|
case TAN:
|
|
cc--;
|
|
mstr[cc]="(sec("+bstr[cc]+")^2*"+mstr[cc]+")";
|
|
bstr[cc]="tan("+bstr[cc]+")";
|
|
|
|
cc++;
|
|
break;
|
|
case CSC:
|
|
cc--;
|
|
mstr[cc]="(-csc("+bstr[cc]+")*cot("+bstr[cc]+")*"+mstr[cc]+")";
|
|
bstr[cc]="csc("+bstr[cc]+")";
|
|
cc++;
|
|
break;
|
|
case SEC:
|
|
cc--;
|
|
mstr[cc]="(sec("+bstr[cc]+")*tan("+bstr[cc]+")*"+mstr[cc]+")";
|
|
bstr[cc]="sec("+bstr[cc]+")";
|
|
cc++;
|
|
break;
|
|
case COT:
|
|
cc--;
|
|
mstr[cc]="(-csc("+bstr[cc]+")^2*"+mstr[cc]+")";
|
|
bstr[cc]="cot("+bstr[cc]+")";
|
|
|
|
cc++;
|
|
case LN:
|
|
cc--;
|
|
mstr[cc]="("+mstr[cc]+"/"+bstr[cc]+")";
|
|
bstr[cc]="ln("+bstr[cc]+")";
|
|
cc++;
|
|
break;
|
|
case LOG10:
|
|
cc--;
|
|
mstr[cc]="("+mstr[cc]+"/"+bstr[cc]+"/ln(10))";
|
|
bstr[cc]="log10("+bstr[cc]+")";
|
|
cc++;
|
|
break;
|
|
case LOG:
|
|
cc--;
|
|
mstr[cc-1]="("+mstr[cc]+"/"+bstr[cc]+"/ln("+bstr[cc-1]+")-ln("+bstr[cc]+")*"+mstr[cc-1]+"/ln("+bstr[cc-1]+")^2/"+bstr[cc-1]+")";
|
|
bstr[cc-1]="log("+bstr[cc-1]+","+bstr[cc]+")";
|
|
mstr[cc]="";
|
|
bstr[cc]="";
|
|
|
|
break;
|
|
default:
|
|
//THROW(new CEvalException("Out of Case"));
|
|
break;
|
|
}
|
|
}
|
|
str=mstr[cc-1];
|
|
delete[] mstr;
|
|
delete[] bstr;
|
|
}*/
|
|
|
|
/*int CPoly::FindIndex(int tval)
|
|
{
|
|
return tval;
|
|
}
|
|
*/
|