📄 formelparser.cpp
字号:
//////////////////////////////////////////////////////////////////////
// FormulaParser.cpp: implementation of the CFormulaParser class.
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "math.h"
#include "Parser.h"
#include "rw_gfa.h"
#include "FormelParser.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CFormulaParser::CFormulaParser()
{
m_strStandardFunction.Add("");
m_strStandardFunction.Add("ABS");
m_strStandardFunction.Add("SQR");
m_strStandardFunction.Add("SINH");
m_strStandardFunction.Add("COSH");
m_strStandardFunction.Add("TANH");
m_strStandardFunction.Add("ARCTAN");
m_strStandardFunction.Add("LN");
m_strStandardFunction.Add("LOG");
m_strStandardFunction.Add("EXP");
m_strStandardFunction.Add("SIN");
m_strStandardFunction.Add("COS");
m_strStandardFunction.Add("TAN");
m_strStandardFunction.Add("ARCSIN");
m_strStandardFunction.Add("ARCCOS");
m_strStandardFunction.Add("INT");
m_strStandardFunction.Add("RAD");
m_strStandardFunction.Add("DEG");
m_strStandardFunction.Add("ARSINH");
m_strStandardFunction.Add("ARCOSH");
m_strStandardFunction.Add("ARTANH");
}
CFormulaParser::~CFormulaParser()
{
}
//////////////////////////////////////////////////////////////////////
// Methoden
//////////////////////////////////////////////////////////////////////
double CFormulaParser::SignFactor(WORD& nPosition, CString& strCharacter)
{
if (strCharacter == "-")
{
Char_n(nPosition, strCharacter);
return (-1.0) * Factor(nPosition, strCharacter);
}
else return Factor(nPosition, strCharacter);
}
double CFormulaParser::Calculation(CString strFormula, double xValue, WORD& ErrorPosition, CString& Errortext)
{
WORD nPosition;
CString strCharacter;
double ergebnis;
char buffer[32];
m_strErrortext.Empty();
try
{
strFormula.TrimLeft();
strFormula.TrimRight();
m_strFunction = strFormula + strChar_(0);
m_dFktValue = xValue;
if (m_dFktValue == 0)
m_dFktValue = 1.0E-99;
nPosition = 0;
Char_n(nPosition, strCharacter);
ergebnis = Expression(nPosition, strCharacter);
if (strCharacter == strChar_(0))
{
Errortext = m_strErrortext;
ErrorPosition = 0;
}
else
{
ErrorPosition = nPosition;
sprintf(buffer, "Error an Position %d gefunden", (int) ErrorPosition);
Errortext = buffer;
Errortext += m_strErrortext;
Errortext += "!";
}
return ergebnis;
}
catch (CException* ex)
{
TCHAR szCause[255];
ex->GetErrorMessage(szCause, 255);
Errortext = _T("Error in Calculation() weil ");
Errortext += szCause;
return 0;
}
}
double CFormulaParser::Expression(WORD& nPosition, CString& strCharacter)
{
CString strOperator;
double erg = SimpleExpression(nPosition, strCharacter);
while (strCharacter == "+" || strCharacter == "-")
{
strOperator = strCharacter;
Char_n(nPosition, strCharacter);
if (strOperator == "+")
erg += SimpleExpression(nPosition, strCharacter);
else if (strOperator == "-")
erg -= SimpleExpression(nPosition, strCharacter);
}
return erg;
}
double CFormulaParser::SimpleExpression(WORD& nPosition, CString& strCharacter)
{
double s,dum;
CString strOperator;
s = Term(nPosition, strCharacter);
while (strCharacter == "*" || strCharacter == "/")
{
strOperator = strCharacter;
Char_n(nPosition, strCharacter);
if (strOperator == "*")
s = s * Term(nPosition, strCharacter);
else if (strOperator == "/")
{
dum = Term(nPosition, strCharacter);
if (dum != 0)
s = s / dum;
else
m_strErrortext = " (Division durch Null)";
}
}
return s;
}
double CFormulaParser::Term(WORD& nPosition, CString& strCharacter)
{
double t,vz;
t = SignFactor(nPosition, strCharacter);
while (strCharacter == "^")
{
Char_n(nPosition, strCharacter);
vz = SignFactor(nPosition, strCharacter);
if ((t <= 0 && fabs(vz) <= 1) || (t <= 0 && vz != int(vz)))
m_strErrortext = " (keine Wurzel aus neg. Zahl)";
else
t = pow(t,vz);
}
return t;
}
double CFormulaParser::Char_n(WORD& nPosition, CString& strCharacter)
{
do
{
nPosition ++; // evtl. nach strCharacter
if (nPosition <= m_strFunction.GetLength())
//war ge鋘dert auf: strCharacter = MID(m_strFunction, nPosition, 1);
strCharacter = m_strFunction.Mid(nPosition - 1, 1);
else
strCharacter = strChar_(0);
// TRACE("strCharacter= "+ strCharacter);
}
while (strCharacter == " ");
return nPosition;
}
void CFormulaParser::SetFormula(CString Formula)
{
m_strFormula = Formula;
}
CString CFormulaParser::GetFormula()
{
return m_strFormula;
}
double CFormulaParser::Factor(WORD& nPosition, CString& strCharacter)
{
double f = 0.0;
BOOL erfolg = false;
WORD wI=0, wL=0, wBeginn=0, wError=0;
wError = 0;
// if (strCharacter == strChar_(0)) return 0.0;
//if ((BYTE) strCharacter[0] >= (BYTE) "0" && (BYTE) strCharacter[0] <= (BYTE) "9" || strCharacter == ".")
if (strCharacter >= "0" && strCharacter <= "9" || strCharacter == ".")
{
wBeginn = nPosition;
do
{
Char_n(nPosition, strCharacter);
}
while ((strCharacter >= "0" && strCharacter <= "9" || strCharacter == "."));
// while (!((BYTE) strCharacter[0] >= (BYTE) "0") && ((BYTE) strCharacter[0] <= (BYTE) "9") || (strCharacter == "."));
if (strCharacter == ".") // Abfrage wird nie abgearbeitet
{
do
{
Char_n(nPosition, strCharacter);
}
while (!((BYTE)strCharacter[0] >= (BYTE)"0") && ((BYTE)strCharacter[0] <= (BYTE)"9") || ((BYTE)strCharacter[0] == (BYTE)"."));
}
f = atof(m_strFunction.Mid(wBeginn - 1, nPosition - wBeginn ));
//original aus VB: f = Val(Mid$(funktion$, beginn%, position% - beginn%))
}
else
{
CString strCharacterUpper = strCharacter;
strCharacterUpper.MakeUpper();
if (strCharacter == "(")
{
Char_n(nPosition, strCharacter);
f = Expression(nPosition, strCharacter);
if (strCharacter == ")")
Char_n(nPosition, strCharacter);
}
else if (strCharacterUpper == "X")
{
Char_n(nPosition, strCharacter);
f = m_dFktValue;
}
else if (strCharacterUpper == "B")
{
Char_n(nPosition, strCharacter);
f = m_dFunctionConstant[1];
}
else if (strCharacterUpper == "F")
{
Char_n(nPosition, strCharacter);
f = m_dFunctionConstant[2];
}
else if (strCharacterUpper == "G")
{
Char_n(nPosition, strCharacter);
f = m_dFunctionConstant[3];
}
else if (strCharacterUpper == "H")
{
Char_n(nPosition, strCharacter);
f = m_dFunctionConstant[4];
}
else if (strCharacterUpper == "J")
{
Char_n(nPosition, strCharacter);
f = m_dFunctionConstant[5];
}
else if (strCharacterUpper == "K")
{
Char_n(nPosition, strCharacter);
f = m_dFunctionConstant[6];
}
else if (strCharacterUpper == "M")
{
Char_n(nPosition, strCharacter);
f = m_dFunctionConstant[7];
}
else if (strCharacterUpper == "N")
{
Char_n(nPosition, strCharacter);
f = m_dFunctionConstant[8];
}
else if (strCharacterUpper == "U")
{
Char_n(nPosition, strCharacter);
f = m_dFunctionConstant[9];
}
else if (strCharacterUpper == "V")
{
Char_n(nPosition, strCharacter);
f = m_dFunctionConstant[10];
}
else
{
erfolg = false;
int AnzStdFunctions = m_strStandardFunction.GetSize() - 1;
for (wI = 1; wI <= AnzStdFunctions; wI++)
{
if (!erfolg)
{
wL = m_strStandardFunction[wI].GetLength();
CString strFunktionUpper = m_strFunction.Mid(nPosition - 1, wL);
strFunktionUpper.MakeUpper();
if (strFunktionUpper == m_strStandardFunction[wI])
{
nPosition = nPosition + wL - 1;
Char_n(nPosition, strCharacter);
f = Factor(nPosition, strCharacter);
if (strFunktionUpper == "ABS")
f = fabs(f);
else if (strFunktionUpper == "SQR")
if (f >= 0)
f = sqrt(f);
else
wError = -1;
else if (strFunktionUpper == "SINH")
f = sinh(f);
else if (strFunktionUpper == "COSH")
f = cosh(f);
else if (strFunktionUpper == "TANH")
f = tanh(f);
else if (strFunktionUpper == "ARCTAN")
f = atan(f);
else if (strFunktionUpper == "LN")
{
if (f >= 0)
f = log(f);
else
wError = -1;
}
else if (strFunktionUpper == "LOG")
{
if (f >= 0)
f = log10(f);
else
wError = -1;
}
else if (strFunktionUpper == "EXP")
{
if (f <= 41)
f = exp(f);
else
wError = -1;
}
else if (strFunktionUpper == "SIN")
f = sin(f);
else if (strFunktionUpper == "COS")
f = cos(f);
else if (strFunktionUpper == "TAN")
{
if (cos(f) != 0)
f = tan(f);
else
wError = -1;
}
else if (strFunktionUpper == "ARCSIN")
{
if (fabs(f) < 1)
f = asin(f);
else
wError = -1;
}
else if (strFunktionUpper == "ARCCOS")
{
if (fabs(f) <= 1)
f = acos(f);
else
wError = -1;
}
else if (strFunktionUpper == "INT")
f = int(f);
else if (strFunktionUpper == "RAD")
f = RAD(f);
else if (strFunktionUpper == "DEG")
f = DEG(f);
else if (strFunktionUpper == "ARSINH")
f = arsinh(f);
else if (strFunktionUpper == "ARCOSH")
{
if (fabs(f) >= 1)
f = arcosh(f);
else
wError = -1;
}
else if (strFunktionUpper == "ARTANH")
{
if (fabs(f) <= 1)
f = artanh(f);
else
wError = -1;
}
erfolg = true;
}
}
}
}
}
if (wError == -1)
m_strErrortext = " (Ein Error wurde abgefangen)";
return f;
}
void CFormulaParser::SetFunctConst(int index, double val)
{
if (index >= 1 && index < 10) //zwischen 0 und 9
m_dFunctionConstant[index] = val;
else
AfxMessageBox("ProgrammError in SetFunctConst()");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -