// StringResolution.cpp: implementation of the CComputer class. #include "stdafx.h" #include "computer.h" #include #include "kernel.h" #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif extern int MyRound(double value); ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// CComputer::CComputer(char*pszFormula) :m_nOprandNum(0),m_nOprandANum(0),m_nOperatorNum(0) { m_pOperator = NULL; m_pOprand = NULL; m_pOprandA = NULL; if (pszFormula) { m_strFormula = pszFormula; Initialize(); } } CComputer::~CComputer() { if (m_pOperator) delete[]m_pOperator; m_pOperator = NULL; if(m_pOprand) delete[]m_pOprand; m_pOprand = NULL; if (m_pOprandA) delete[]m_pOprandA; m_pOprandA = NULL; } void CComputer::SetFormula(CString strFormula) { if (!strFormula) { return; } m_strFormula = strFormula; if (m_pOperator) { delete[]m_pOperator; m_pOperator = NULL; } if (m_pOprand) { delete[]m_pOprand; m_pOprand = NULL; } if (m_pOprandA) { delete[]m_pOprandA; m_pOprandA = NULL; } m_nOprandNum = 0,m_nOprandANum = 0,m_nOperatorNum = 0; Initialize(); } int CComputer::IsFormula() { stack charStack; int i,num = m_strFormula.GetLength(); char notChar[] = {';','\'',':',' ','[',']','{','}','\\','|',',','\"','&','%','$','@','#','`','~','?'};//'!', modify by 2012.06.01 int notNum = sizeof(notChar); for (i=0;i",s)); return -i-1;//the ith symbol is invalidating. } } } for (i=0;im_strName); delete od; return value; } else { while (!Oprand.empty()) { COperand*od = Oprand.top(); Oprand.pop(); delete od; } return BIGNUMBER; } } OperatorStack tmpOO; OperandStack tmpOD; COperator* op = 0,*op1 = 0; COperand *oprand = 0,*oprand1 = 0; op = Operator.top(); Operator.pop(); if (!Operator.empty()) { op1 = Operator.top(); } while (op1&&(op1->m_nLevel > op->m_nLevel)) { tmpOO.push(op); if (op->m_nType==BINARY) { if (!Oprand.empty()) { oprand = Oprand.top(); Oprand.pop(); tmpOD.push(oprand); } } op = op1; Operator.pop(); if (!Operator.empty()) { op1 = Operator.top(); } else { op1 = 0; } } if (op->m_nType==UNARY) { if (Oprand.empty()) { return BIGNUMBER; } oprand = Oprand.top(); double x = computing(op,oprand); oprand->m_strName.Format("%g",x); } else { if (Oprand.empty()) { return BIGNUMBER; } oprand1 = Oprand.top(); Oprand.pop(); if (Oprand.empty()) { return BIGNUMBER; } oprand = Oprand.top(); double x = computing(op,oprand1,oprand); oprand->m_strName.Format("%g",x); delete oprand1; } delete op; while (!tmpOO.empty()) { op = tmpOO.top(); tmpOO.pop(); Operator.push(op); } while (!tmpOD.empty()) { oprand = tmpOD.top(); tmpOD.pop(); Oprand.push(oprand); } return Computer(Operator,Oprand); } double CComputer::computer(double variantValue[], int num) { double value = 0.0; int i; if (numm_strName.Format("%g",variantValue[j]); } } Oprand.push(od); } value = Computer(Operator,Oprand); return value; } CString CComputer::GetErrorInformation() { CString value; return value; } BOOL CComputer::EmptyStack(OperatorStack Op) { while(!Op.empty()) { COperator*op = Op.top(); Op.pop(); delete op; } return TRUE; } BOOL CComputer::EmptyStack(OperandStack Od) { while (!Od.empty()) { COperand*od = Od.top(); Od.pop(); delete od; } return TRUE; } BOOL CComputer::GetOperatorStack(OperatorStack &Operator, CString &string) { BOOL bRet = TRUE; int num = string.GetLength(); int i = 0; int level = 0; while (im_nLevel = level; op->m_strOperator = string.Mid(i,1); op->m_nStartIndex = i; if(i==0||string[i-1]=='#') { op->m_nType = UNARY; } else { op->m_nType = BINARY; } Operator.push(op); string.SetAt(i,'@'); i++; } else if (string[i]=='*'||string[i]=='/') { COperator* op = new COperator; op->m_nLevel = level+1; op->m_strOperator = string.Mid(i,1); op->m_nStartIndex = i; op->m_nType = BINARY; Operator.push(op); string.SetAt(i,'@'); i++; } else if (string[i]=='^') { COperator* op=new COperator; op->m_nLevel = level+2; op->m_strOperator = string.Mid(i,1); op->m_nStartIndex = i; op->m_nType = BINARY; Operator.push(op); string.SetAt(i,'@'); i++; } else if (string.Mid(i,4)=="SQRT") { COperator* op=new COperator; op->m_nLevel = 3+level; op->m_strOperator = "SQRT"; op->m_nStartIndex = i; op->m_nType = UNARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@');string.SetAt(i+3,'@'); i+=3; } else if (string.Mid(i,3)=="LOG") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "LOG"; op->m_nStartIndex = i; op->m_nType = UNARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@'); i+=3; } else if (string.Mid(i,3)=="SIN") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "SIN"; op->m_nStartIndex = i; op->m_nType = UNARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@'); i+=3; } else if (string.Mid(i,3)=="COS") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "COS"; op->m_nStartIndex = i; op->m_nType = UNARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@'); i+=3; } else if (string.Mid(i,3)=="TAN") { COperator* op=new COperator; op->m_nLevel = 3+level; op->m_strOperator = "TAN"; op->m_nStartIndex = i; op->m_nType = UNARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@'); i+=3; } else if (string.Mid(i,3)=="COT") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "COT"; op->m_nStartIndex = i; op->m_nType = UNARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@'); i+=3; } else if (string.Mid(i,4)=="ASIN") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "ASIN"; op->m_nStartIndex = i; op->m_nType = UNARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@');string.SetAt(i+3,'@'); i+=3; } else if (string.Mid(i,4)=="ACOS") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "ACOS"; op->m_nStartIndex = i; op->m_nType = UNARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@');string.SetAt(i+3,'@'); i+=3; } else if (string.Mid(i,4)=="ATAN") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "ATAN"; op->m_nStartIndex = i; op->m_nType = UNARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@');string.SetAt(i+3,'@'); i+=3; } else { i++; } } return bRet; } BOOL CComputer::GetOperandStack(OperandStack &Oprand, CString &string) { int i = 0; int num = string.GetLength(); while (im_bIsConst = TRUE; } oprand->m_nStartIndex = i; BOOL HasPoint = FALSE; while (im_bIsConst&&!isdigit(string[i])&&(string[i]!='.')) { CString s; s.Format("Variant cann't start with digital (%d in expression)!",i+1-oprand->m_strName.GetLength()); if( oprand ) delete oprand; return FALSE; } oprand->m_strName+=string.Mid(i,1); i++; } Oprand.push(oprand); } } return TRUE; } int CComputer::GetErrorNumber() { return 0; } double CComputer::computing(const COperator*op,const COperand*oprand) { double x = atof(oprand->m_strName); if (op->m_strOperator=="-") { x = -x; } else if (op->m_strOperator=="LOG") { if(x>0) { x = log(x); } else { x = BIGNUMBER; } } else if (op->m_strOperator=="SQRT") { if ( x>=0 ) { x = sqrt(x); } else { x = BIGNUMBER; } } else if (op->m_strOperator=="SIN") { x = sin(x); } else if (op->m_strOperator=="COS") { x = cos(x); } else if (op->m_strOperator=="TAN") { x = tan(x); } else if (op->m_strOperator=="COT") { if(fabs(sin(x))>DERROR) { x = cos(x)/sin(x); } else { x = BIGNUMBER; } } else if (op->m_strOperator=="ASIN") { x = asin(x); } else if (op->m_strOperator=="ACOS") { x = acos(x); } else if (op->m_strOperator=="ATAN") { x = atan(x); } return x; } double CComputer::computing(const COperator*op,const COperand*Loprand,const COperand*Roprand) { double x = BIGNUMBER; switch(op->m_strOperator[0]) { case '+': x = atof(Loprand->m_strName)+atof(Roprand->m_strName); break; case '-': x = atof(Loprand->m_strName)-atof(Roprand->m_strName); break; case '*': x = atof(Loprand->m_strName)*atof(Roprand->m_strName); break; case '/': { double y = atof(Roprand->m_strName); x = atof(Loprand->m_strName); if (fabs(y)>DERROR) { x = x/y; } else { x = BIGNUMBER; } } break; case '^': { double y = atof(Roprand->m_strName); x = atof(Loprand->m_strName); x = pow(x,y); } break; } return x; } CString CComputer::GetDigitalString(double* variantValue,int num) { CString value=m_strFormula; if (num>=m_nOprandANum) { int i,j; CString* ppchar; ppchar=new CString[m_nOprandNum+1]; for (i=0;i<=m_nOprandNum;i++) { if (i==0) { ppchar[0]=m_strFormula.Left(m_pOprand[0].m_nStartIndex); } else if (im_nLevel = level; op->m_strOperator = string.Mid(i,1); op->m_nStartIndex = i; if(i==0||string[i-1]=='#') { op->m_nType=UNARY; } else { op->m_nType = BINARY; } Operator.push(op); string.SetAt(i,'@'); i++; } else if (string[i]=='*'||string[i]=='/') { COperator* op = new COperator; op->m_nLevel = level+1; op->m_strOperator = string.Mid(i,1); op->m_nStartIndex = i; op->m_nType = BINARY; Operator.push(op); string.SetAt(i,'@'); i++; } else if (string[i]=='^') { COperator* op = new COperator; op->m_nLevel = level+2; op->m_strOperator = string.Mid(i,1); op->m_nStartIndex = i; op->m_nType = BINARY; Operator.push(op); string.SetAt(i,'@'); i++; } else if (string.Mid(i,4)=="SQRT") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "SQRT"; op->m_nStartIndex = i; op->m_nType = UNARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@');string.SetAt(i+3,'@'); i+=4; } else if (string.Mid(i,3)=="LOG") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "LOG"; op->m_nStartIndex = i; op->m_nType = UNARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@'); i+=3; } else if (string.Mid(i,3)=="SIN") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "SIN"; op->m_nStartIndex = i; op->m_nType = UNARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@'); i+=3; } else if (string.Mid(i,3)=="COS") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "COS"; op->m_nStartIndex = i; op->m_nType = UNARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@'); i+=3; } else if (string.Mid(i,3)=="TAN") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "TAN"; op->m_nStartIndex = i; op->m_nType = UNARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@'); i+=3; } else if (string.Mid(i,3)=="COT") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "COT"; op->m_nStartIndex = i; op->m_nType = UNARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@'); i+=3; } else if (string.Mid(i,4)=="ASIN") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "ASIN"; op->m_nStartIndex = i; op->m_nType = UNARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@');string.SetAt(i+3,'@'); i+=4; } else if (string.Mid(i,4)=="ACOS") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "ACOS"; op->m_nStartIndex = i; op->m_nType = UNARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@');string.SetAt(i+3,'@'); i+=4; } else if (string.Mid(i,4)=="ATAN") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "ATAN"; op->m_nStartIndex = i; op->m_nType = UNARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@');string.SetAt(i+3,'@'); i+=4; } else if (string.Mid(i,3)=="ABS") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "ABS"; op->m_nStartIndex = i; op->m_nType = UNARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@'); i+=3; } else if (string.Mid(i,3)=="MOD") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "MOD"; op->m_nStartIndex = i; op->m_nType = BINARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@'); i+=3; } else if (string.Mid(i,3)=="RND") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "RND"; op->m_nStartIndex = i; op->m_nType = UNARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@'); i+=3; } else if (string.Mid(i,2)=="==") { COperator* op = new COperator; op->m_nLevel=3+level; op->m_strOperator = "=="; op->m_nStartIndex = i; op->m_nType = BINARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@'); i+=2; } else if (string.Mid(i,2)==">=") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = ">="; op->m_nStartIndex = i; op->m_nType = BINARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@'); i+=2; } else if (string.Mid(i,2)=="<=") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "<="; op->m_nStartIndex = i; op->m_nType = BINARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@'); i+=2; } else if (string.Mid(i,2)=="!=")//modify by 2012.06.01 <> { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "!="; op->m_nStartIndex = i; op->m_nType = BINARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@'); i+=2; } else if (string[i]=='>') { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = ">"; op->m_nStartIndex = i; op->m_nType = BINARY; Operator.push(op); string.SetAt(i,'@'); i++; } else if (string[i]=='<') { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "<"; op->m_nStartIndex = i; op->m_nType = BINARY; Operator.push(op); string.SetAt(i,'@'); i++; } else if (string.Mid(i,3)=="NOT") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "NOT"; op->m_nStartIndex = i; op->m_nType = UNARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@'); i+=3; } else if (string.Mid(i,3)=="AND") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "AND"; op->m_nStartIndex = i; op->m_nType = BINARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@'); i+=3; } else if (string.Mid(i,2)=="OR") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "OR"; op->m_nStartIndex = i; op->m_nType = BINARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@'); i+=2; } else if (string.Mid(i,3)=="XOR") { COperator* op = new COperator; op->m_nLevel = 3+level; op->m_strOperator = "XOR"; op->m_nStartIndex = i; op->m_nType = BINARY; Operator.push(op); string.SetAt(i,'@');string.SetAt(i+1,'@');string.SetAt(i+2,'@'); i+=3; } else { i++; } } return bRet; } double CRealComputer::computing(const COperator*op,const COperand*oprand) { double x = atof(oprand->m_strName); if (op->m_strOperator=="-") { x = -x; } else if (op->m_strOperator=="SQRT") { if (x>=0) { x = sqrt(x); } else { x = BIGNUMBER; } } else if (op->m_strOperator=="SIN") { x = sin(x); } else if (op->m_strOperator=="COS") { x = cos(x); } else if (op->m_strOperator=="TAN") { x = tan(x); } else if (op->m_strOperator=="COT") { if (fabs(sin(x))>DERROR) { x = cos(x)/sin(x); } else { x = BIGNUMBER; } } else if (op->m_strOperator=="NOT") { if (x!=0) { x = 0; } else { x = 1; } } else if (op->m_strOperator=="RND") { x = (int)x; } return x; } double CRealComputer::computing(const COperator*op,const COperand*Loprand,const COperand*Roprand) { double x = BIGNUMBER; switch (op->m_strOperator[0]) { case '+': x = atof(Loprand->m_strName)+atof(Roprand->m_strName); break; case '-': x = atof(Loprand->m_strName)-atof(Roprand->m_strName); break; case '*': x = atof(Loprand->m_strName)*atof(Roprand->m_strName); break; case '/': { double y = atof(Roprand->m_strName); x = atof(Loprand->m_strName); if (fabs(y)>DERROR) { x = x/y; } else { x = BIGNUMBER; } } break; case '^': { double y = atof(Roprand->m_strName); x = atof(Loprand->m_strName); x = pow(x,y); } break; } if (op->m_strOperator=="==") { if (MyRound(atof(Loprand->m_strName)) == MyRound(atof(Roprand->m_strName)) ) { x = 1; } else { x = 0; } } else if (op->m_strOperator==">=") { if (atof(Loprand->m_strName)>=atof(Roprand->m_strName)) { x = 1; } else { x = 0; } } else if (op->m_strOperator=="<=") { if (atof(Loprand->m_strName)<=atof(Roprand->m_strName)) { x = 1; } else { x = 0; } } else if (op->m_strOperator=="!=") { if (atof(Loprand->m_strName)!=atof(Roprand->m_strName)) { x = 1; } else { x = 0; } } else if (op->m_strOperator==">") { if (atof(Loprand->m_strName)>atof(Roprand->m_strName)) { x = 1; } else { x = 0; } } else if (op->m_strOperator=="<") { if (atof(Loprand->m_strName)m_strName)) { x = 1; } else { x = 0; } } else if (op->m_strOperator=="AND") { if (MyRound(atof(Loprand->m_strName)) && MyRound(atof(Roprand->m_strName))) { x = 1; } else { x = 0; } } else if (op->m_strOperator=="OR") { if (MyRound(atof(Loprand->m_strName)) || MyRound(atof(Roprand->m_strName))) { x = 1; } else { x = 0; } } else if(op->m_strOperator=="XOR") { if (MyRound(atof(Loprand->m_strName))&&MyRound(atof(Roprand->m_strName))) { x = 0; } else if ((!MyRound(atof(Loprand->m_strName))) && (!MyRound(atof(Roprand->m_strName)))) { x = 0; } else { x = 1; } } else if (op->m_strOperator=="MOD") { x =MyRound(atof(Loprand->m_strName)) % MyRound(atof(Roprand->m_strName)); } return x; } int CRealComputer::IsFormula() { stack charStack; int i,num=m_strFormula.GetLength(); char notChar[] = {';','\'',':',' ','[',']','{','}','\\','|',',','&','%','$','@','#','`','~','?'};//'!', modify by 2012.06.01 int notNum = sizeof notChar; for (i=0;iGetAnalogValue(m_pOprandA[i].m_strName); //if( -1 != m_formula.Find("Caross_1_StartORShutStatus") ) // LOG4C((LOG_NOTICE, "m_strDynShow = < %s >,m_oprandA[i].m_name=%s, m_oprandANum = %d",m_formula,m_oprandA[i].m_name,m_oprandANum )); if ( (int)tmp!=VARIANT_NOTFOUND ) { data[i] = tmp; } else { } } double result = computer(data, m_nOprandANum); return result; }