⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 formelparser.cpp

📁 mfc 高级计算器源代码
💻 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 + -