CFormula 表达式计算

//.h

#pragma once

#include <ComDef.h>

#include <math.h>

 

 

 

//#define VAL_TYPE       __int32

#define VAL_TYPE       __int64

 

 

#define MString              _bstr_t

 

 

class CFormula

{

public:

       CFormula(void);

       virtual ~CFormula(void);

 

       BOOL Load(CHAR * pFormula, double * pdRetVal, _bstr_t * pbStrResult = NULL);

       BOOL GetResultString(_bstr_t * pbStrError);

 

       BOOL CalcuLoop(CHAR * pFormula);

       BOOL CalcuSimple(CHAR * pFormula, int nSignPos, long double * pdRet);

       BOOL CalcuFunction(CHAR * pFormula, int nFunIndex, long double * pdRet);

 

 

       BOOL GetKnowSign(_bstr_t * pbStrSign);

       BOOL GetKnowFunction(_bstr_t * pbStrFunction);

 

//protected:

 

       BOOL IdentifyMinus(CHAR *pFormula, int nPos);

       int  GetFunsIndex(CHAR *pFormula, int nBracketPos, int * pFunStart);

 

       int  GetFirstCalcu(CHAR * pFormula, _bstr_t * pbStrLeft, _bstr_t * pbStrRight, _bstr_t * pbStrFirst, int *pnFirstSignPos);

       BOOL GetSimpleFirstCalcu(CHAR * pFormula, int *pnLeftPos, int *pnRightPos, int *pSignPos);

 

       BOOL FormulaCutCenter(CHAR * pFormula, int nLeft, int nRight,

              _bstr_t * pbStrLeft, _bstr_t * pbStrRight, _bstr_t * pbStrCenter);

 

       BOOL GetFirstBracket(CHAR * pFormula, int * pLeftPos, int * pRightPos);

 

       static CHAR * LongDouble2a(long double ldValue, MString *pString);

       static long double a2LongDouble(CHAR *pString);

 

 

public:

 

 

 

 

       long double       m_dRetVal;

       _bstr_t          m_bStrFormula;

       _bstr_t          m_bStrResult;

};

 

 

#define MY_FUN_TYPE WINAPIV

 

typedef long double * (MY_FUN_TYPE * MY_FUNCTION)(DWORD, long double *);

 

 

 

 

//   函数实现

long double * MY_FUN_TYPE MyMax(DWORD dwAryCount, long double * pArry);

long double * MY_FUN_TYPE MyMin(DWORD dwAryCount, long double * pArry);

long double * MY_FUN_TYPE MyPow(DWORD dwAryCount, long double * pArry);

long double * MY_FUN_TYPE MyCos(DWORD dwAryCount, long double * pArry);

long double * MY_FUN_TYPE MySin(DWORD dwAryCount, long double * pArry);

long double * MY_FUN_TYPE MyLog(DWORD dwAryCount, long double * pArry);

 

long double * MY_FUN_TYPE MyDgr(DWORD dwAryCount, long double * pArry);

long double * MY_FUN_TYPE MySum(DWORD dwAryCount, long double * pArry);

long double * MY_FUN_TYPE MyAvg(DWORD dwAryCount, long double * pArry);

//   factorial 阶乘

long double * MY_FUN_TYPE MyFtrl(DWORD dwAryCount, long double * pArry);

//   拉格朗日值算法

long double * MY_FUN_TYPE MyLgrg(DWORD dwAryCount, long double * pArry);

 

 

 

 

 

 

 

 

 

 

 

 

//.cpp

#include "Formula.h"

#include "stdio.h"

#include <math.h>

#include "../ComFun/ComFun.h"

 

CFormula::CFormula(void)

{

}

 

CFormula::~CFormula(void)

{

}

 

#define       bracket                     '('

#define DOUBLE_MAX           1.0E308

#define DOUBLE_MIN              -1.0E308

#define MAX_SIGN_LEVEL  100000

 

//3.14159265358979323846264338327950288419716939937510

#define PI                        3.141592653589793238

#define PI_STR                "3.141592653589793238"

 

static long double         s_dFunRet;

 

 

#define GET_FUN(_Fun)       ((MY_FUNCTION)(&(DWORD &)(_Fun)))

//#define GET_FUN(_Fun)  ((VOID *)(&(DWORD &)(_Fun)))

 

typedef struct _FUNCTION

{

       CHAR          szFunName[100];

       MY_FUNCTION       pFun;

       DWORD              dwFunParams;

       int                nFunNameLen;

}FUNCTION;

 

static FUNCTION Function[] =

{

       {"MAX",        MyMax, 0, 3},

       {"MIN",          MyMin,  0, 3},

       {"POW",              MyPow,       2, 3},

       {"COS",         MyCos,  1, 3},

       {"SIN",          MySin,   1, 3},

       {"LOG",        MyLog, 2, 3},

       {"DGR",        MyDgr,  1, 3},

       {"SUM",        MySum, 0, 3},

       {"AVG",        MyAvg, 0, 3},    //平均值

       {"FTRL",       MyFtrl,  1, 4},    //阶乘

       {"LGRG",       MyLgrg,       0, 4},       //拉格朗日数值插值

      {"", NULL, 0, 0}

};

 

long double * MyMin(DWORD dwAryCount, long double * pArry)

{

       return &s_dFunRet;

}

 

long double * MyMax(DWORD dwAryCount, long double * pArry)

{

       DWORD              i;

 

       s_dFunRet = DOUBLE_MIN;

       for(i=0; i<dwAryCount; i++)

       {

              if(pArry[i] > s_dFunRet)

                     s_dFunRet = pArry[i];

       }

 

       return &s_dFunRet;

}

 

long double * MyPow(DWORD dwAryCount, long double * pArry)

{

       s_dFunRet = pow(pArry[0], pArry[1]);

       return &s_dFunRet;

}

 

 

long double * MyCos(DWORD dwAryCount, long double * pArry)

{

       s_dFunRet = cos(pArry[0]);

       return &s_dFunRet;

}

 

long double * MySin(DWORD dwAryCount, long double * pArry)

{

       s_dFunRet = sin(pArry[0]);

       return &s_dFunRet;

}

 

long double * MyLog(DWORD dwAryCount, long double * pArry)

{

       if(dwAryCount == 1)

        s_dFunRet = log(pArry[0]);

       else

              s_dFunRet = log(pArry[1])/log(pArry[0]);

 

       return &s_dFunRet;

}

 

long double * MyDgr(DWORD dwAryCount, long double * pArry)

{

       s_dFunRet = pArry[0]*PI/180.0;

       return &s_dFunRet;

}

 

long double * MySum(DWORD dwAryCount, long double * pArry)

{

       DWORD              i;

 

       s_dFunRet = 0.0;

       for(i=0; i<dwAryCount; i++)

       {

              s_dFunRet += pArry[i];

       }

 

       return &s_dFunRet;

}

 

long double * MyAvg(DWORD dwAryCount, long double * pArry)

{

       DWORD              i;

 

       s_dFunRet = 0.0;

       for(i=0; i<dwAryCount; i++)

       {

              s_dFunRet += pArry[i];

       }

       s_dFunRet /= dwAryCount;

 

       return &s_dFunRet;

}

 

//   factorial 阶乘

long double * MyFtrl(DWORD dwAryCount, long double * pArry)

{

       int         nValue, i;

       nValue = (int)pArry[0];

       s_dFunRet = 1.0;

 

       for(i=2; i<=nValue; i++)

       {

              s_dFunRet *= i;

       }

 

       return &s_dFunRet;

}

 

 

long double Lagrange(int n, long double *px, long double *py, double x)

{

       double s1, s2, y = 0.0;

       int i1, i2;

       n--;

      for (i1 = 0; i1 <= n; i1++)

       {

              s1 = 1.0;

              s2 = 1.0;

              for (i2 = 0; i2 <= n; i2++)

              {

                     if (i2 != i1)

                     {

                            s1 *= (x - px[i2]);

                            s2 *= (px[i1] - px[i2]);

                     }

              }

              y += py[i1] * s1 / s2;

       }

       return y;

}

 

long double * MyLgrg(DWORD dwAryCount, long double * pArry)

{

       int                nCount, i;

       long double       dAx[256], dAy[256], x, y;

 

       nCount = dwAryCount / 2;

 

       for(i=0; i<nCount; i++)

       {

              dAx[i] = pArry[i*2];

              dAy[i] = pArry[i*2+1];

       }

       x = pArry[i*2];

 

       y = Lagrange(nCount, dAx, dAy, x);

       s_dFunRet = y;

 

       return &s_dFunRet;

}

 

 

 

typedef struct _SIGN

{

       CHAR       szSign[10];

       int         nOrder;

       int         nSignLen;

}SIGN, PSIGN;

 

static SIGN       Sign[]    =

{     

       {"+",      1, 1},

       {"-",       1, 1},

       {"*", 0, 1},

       {"/",       0, 1},

       {"%",      0, 1},

       {"^", 2, 1},

       {"&",      2, 1},

       {"|", 2, 1},

       {"<<",   2, 2},

       {">>",   2, 2},

       {0  ,  -1, 0}

};

 

typedef struct _REPLACE

{

       CHAR       szOldStr[32];

       CHAR       szNewStr[32];

}REPLACE;

 

static REPLACE       Replace[]       =

{     

       {"{", "("},

       {"[", "("},

       {"}", ")"},

       {"]", ")"},

       {"PI", PI_STR},

       {"", ""}

};

 

int GetSignIndex(CHAR * pStr, int nPos, int *pnSignLevl = NULL)

{

       int         i;

       int         nIndex = -1;

       for(i=0; ; i++)

       {

              if(Sign[i].szSign[0] == '/0')

                     return nIndex;

 

              if(strncmp(pStr+nPos, Sign[i].szSign, Sign[i].nSignLen) == 0)

              {

                     if(pnSignLevl)

                            *pnSignLevl = Sign[i].nOrder;

                     return i;

              }

              else if(pStr[nPos] == Sign[i].szSign[1])

              {

                     nIndex = -2;

              }

       }

       return nIndex;

}

 

 

 

BOOL CFormula::Load(CHAR * pFormula, double * pdRetVal, _bstr_t * pbStrResult)

{

       int         i, nLen;

       m_bStrResult = "";

 

 

       CHAR       *pNewStr;

       nLen = (int)strlen(pFormula);

       pNewStr = (CHAR *)malloc(nLen*10+1);

       strcpy(pNewStr, pFormula);

       strupr(pNewStr);

       for(i=0; ; i++)

       {

              if(Replace[i].szOldStr[0] == 0)

                     break;

              StrReplace(pNewStr, Replace[i].szOldStr, Replace[i].szNewStr);

       }

 

       m_bStrFormula = pNewStr;

       free(pNewStr);

 

       m_bStrResult = "";

       CalcuLoop(m_bStrFormula);

 

       if(pdRetVal)

        *pdRetVal = m_dRetVal;

       if(pbStrResult)

              *pbStrResult = m_bStrResult;

 

       return TRUE;

}

 

BOOL CFormula::CalcuLoop(CHAR * pFormula)

{

       _bstr_t          bStrLeft, bStrRight, bStrFirst, bStrNewFormula;

       _bstr_t          bStrRet;

       long double       dRetVal;

       int                nSignPos, nRetVal, nFunIndex;

 

       nRetVal = GetFirstCalcu(pFormula, &bStrLeft, &bStrRight, &bStrFirst, &nSignPos);

       if(nRetVal <= 0)

       {

              _bstr_t          bStrRet;

              long double       dValue;

              VAL_TYPE nValue;

              CHAR          szHex[256];

 

              if(nRetVal == 0)

            dValue = a2LongDouble(pFormula);

              else

                     dValue = a2LongDouble(bStrFirst);

 

              Double2Str(dValue, &bStrRet);

 

 

              nValue = (VAL_TYPE)dValue;

 

              if(sizeof(VAL_TYPE) == 8)

            sprintf(szHex, "HEX: 0x%016I64X/r/n"

                            "unsigned: %I64u signed: %I64d/r/n", nValue, nValue, nValue);

              else

            sprintf(szHex, "HEX: 0x%08X DWORD: %u INT: %d/r/n", nValue, nValue, nValue);

 

              bStrRet += "/r/n";

              bStrRet += szHex;

 

              m_bStrResult += "=";

              m_bStrResult += bStrRet;

              m_bStrResult += "/r/n";

              return TRUE;

       }

 

       m_bStrResult += "=";

       m_bStrResult += bStrLeft;

       m_bStrResult += "[";

       m_bStrResult += bStrFirst;

       m_bStrResult += "]";

       m_bStrResult += bStrRight;

       m_bStrResult += "/r/n";

 

       if(nRetVal == 1)

       {

              CalcuSimple(bStrFirst, nSignPos, &dRetVal);

       }

       else

       {

              nFunIndex = nSignPos;

              CalcuFunction(bStrFirst, nFunIndex, &dRetVal);

       }

 

       Double2Str(dRetVal, &bStrRet);

 

       bStrNewFormula = bStrLeft;

       bStrNewFormula += bStrRet;

       bStrNewFormula += bStrRight;

 

       return CalcuLoop(bStrNewFormula);

}

 

BOOL CFormula::CalcuSimple(CHAR * pFormula, int nSignPos, long double * pdRet)

{

       long double       dLeft, dRight, dRetVal, dZero = 0.0;

       int                nSignIndex;

       CHAR          cSign;

       nSignIndex = GetSignIndex(pFormula, nSignPos, NULL);

       if(nSignIndex < 0)

       {

              *pdRet = 0.0;

              return FALSE;

       }

 

       cSign = pFormula[nSignPos];

       pFormula[nSignPos] = 0;

 

       dLeft = a2LongDouble(pFormula);

       dRight = a2LongDouble(pFormula + nSignPos + Sign[nSignIndex].nSignLen);

 

       switch(cSign)

       {

       case '+':       dRetVal = dLeft + dRight;

              break;

       case '-':       dRetVal = dLeft - dRight;

              break;

       case '*':       dRetVal = dLeft * dRight;

              break;

       case '/':       dRetVal = dLeft / dRight;

              break;

       case '%':      

              if((int)dRight == 0)

                     dRetVal = dLeft / dZero;

              else

            dRetVal = (long double)(((VAL_TYPE)dLeft) % ((VAL_TYPE)dRight));

              break;

       case '&':       dRetVal = (long double)(((VAL_TYPE)dLeft) & ((VAL_TYPE)dRight));

              break;

       case '|':       dRetVal = (long double)(((VAL_TYPE)dLeft) | ((VAL_TYPE)dRight));

              break;

       case '^':       dRetVal = (long double)(((VAL_TYPE)dLeft) ^ ((VAL_TYPE)dRight));

              break;

       case '<':       dRetVal = (long double)(((VAL_TYPE)dLeft) << ((VAL_TYPE)dRight));

              break;

       case '>':       dRetVal = (long double)(((VAL_TYPE)dLeft) >> ((VAL_TYPE)dRight));

              break;

 

       default:

              return FALSE;

       }

       *pdRet = dRetVal;

       m_dRetVal = dRetVal;

 

       return TRUE;

}

 

int StringToParams(long double * pParams, CHAR * pString, int nCount = 0)

{

       CHAR   * pAryParam, * pOneParam;

       int         i;

       DWORD       dwCount;

 

       if(nCount > 256)

              return FALSE;

       pAryParam = (CHAR *)malloc(256*1024);

       dwCount = StrtoFormatArry(pString, pAryParam, 256, 1024);

 

 

       if(nCount == 0)

       {

              nCount = dwCount;

       }

       else if((int)dwCount < nCount)

       {

//          BREAKIF(TRUE);

//          nCount = dwCount;

       }

       nCount = dwCount;

 

       for(i=0; i<nCount; i++)

       {

              pOneParam = pAryParam + 1024*i;

              pParams[i] = CFormula::a2LongDouble(pOneParam);

       }

       free(pAryParam);

 

       return nCount;

}

 

DWORD InvokeCFun(int nFunParams, ...)

{

       int                i;

       DWORD              dwRetVal, dwParam[10];

       DWORD              dwTemp, dwEsp;

       va_list           marker;

       VOID            * pFun;

 

       dwEsp = nFunParams*sizeof(DWORD);

 

       va_start(marker, nFunParams);

       pFun = (VOID *)va_arg(marker, VOID *);

 

       for(i=0; i<nFunParams; i++)

       {

              dwParam[i] = va_arg(marker, DWORD);

       }

 

       for(i=nFunParams-1; i>=0; i--)       //参数压栈是倒序的

       {

              dwTemp = dwParam[i];

              __asm push dwTemp

       }

 

       __asm

       {

              call pFun

              mov dwRetVal, eax

              add esp, dwEsp               //C形式函数需要恢复栈

       }

 

       va_end(marker);

 

       return dwRetVal;

}

 

BOOL CFormula::CalcuFunction(CHAR * pFormula, int nFunIndex, long double * pdRet)

{

//       LogStr("D://LogStr.log", "CalcuFunction: %s", pFormula);

       CHAR       *pCopy, * pNewFormula;

       pCopy = MallocByStr(pFormula);

       pNewFormula = pCopy;

 

       long double         dFunRet = 1.0, * pRetVal;

       long double         dAryParam[256];

       int                       nParamCount;

 

       memset(dAryParam, 0, sizeof(dAryParam));

 

       BREAKIF(strncmp(pFormula, Function[nFunIndex].szFunName,

              Function[nFunIndex].nFunNameLen) != 0);

 

       nParamCount = Function[nFunIndex].dwFunParams;

       if(nParamCount == 0)

       {

              pNewFormula += Function[nFunIndex].nFunNameLen + 1;

              StrReplaceChar(pNewFormula, ',', ' ');

              nParamCount = StringToParams(dAryParam, pNewFormula);

              pRetVal = Function[nFunIndex].pFun(nParamCount, dAryParam);

              dFunRet = *pRetVal;

       }

       else

       {

              int         nParamRealCount;

              pNewFormula += Function[nFunIndex].nFunNameLen + 1;

              StrReplaceChar(pNewFormula, ',', ' ');

              nParamRealCount = StringToParams(dAryParam, pNewFormula, nParamCount);

              if(nParamRealCount != nParamCount)

              {

//                 BREAKIF(TRUE);

              }

 

              pRetVal = Function[nFunIndex].pFun(nParamRealCount, dAryParam);

              dFunRet = *pRetVal;

       }

       free(pCopy);

 

       *pdRet = dFunRet;

       return TRUE;

}

 

BOOL CFormula::FormulaCutCenter(CHAR * pFormula, int nLeft, int nRight,

                                     _bstr_t * pbStrLeft, _bstr_t * pbStrRight, _bstr_t * pbStrCenter)

{

       CHAR          * pCopyFormula;

       pCopyFormula = MallocByStr(pFormula);

       pCopyFormula[nLeft] = '/0';

 

       *pbStrLeft = pCopyFormula;

       *pbStrRight = pCopyFormula+nRight;

       free(pCopyFormula);

 

       pCopyFormula = MallocByStr(pFormula);

       pCopyFormula[nRight] = '/0';

       *pbStrCenter = pCopyFormula+nLeft;

       free(pCopyFormula);

 

       return TRUE;

}

 

//   找第一次需要计算的步骤       pnFirstSignPos当是函数时作为FunIndex

int CFormula::GetFirstCalcu(CHAR * pFormula, _bstr_t * pbStrLeft, _bstr_t * pbStrRight, _bstr_t * pbStrFirst, int *pnFirstSignPos)

{

       BOOL           bRetVal;

       int                nBktLeft, nBktRight, nRetVal;

       int                nLeft, nRight, nSignPos;

       CHAR   *       pCopyFormula;

       _bstr_t          bStrLeft, bStrRight, bStrCenter;

       _bstr_t          bStrFormat;

       _bstr_t          bStrFirst;

 

       CHAR   * pSimpleFormula;

 

       pSimpleFormula = pFormula;

 

       bRetVal = GetFirstBracket(pFormula, &nBktLeft, &nBktRight);       //找括号

       if(bRetVal == FALSE)       //没找到括号

       {

              bRetVal = GetSimpleFirstCalcu(pSimpleFormula, &nLeft, &nRight, &nSignPos);

              if(bRetVal == FALSE)

                     return 0;       //没用运算符或函数, 计算完成

 

              FormulaCutCenter(pFormula, nLeft, nRight, &bStrLeft, &bStrRight, &bStrCenter);

 

              *pbStrLeft = bStrLeft;

              *pbStrRight = bStrRight;

              *pbStrFirst = bStrCenter;

              *pnFirstSignPos = nSignPos;

              return 1;

       }

 

       //   找到了括号

       FormulaCutCenter(pFormula, nBktLeft+1, nBktRight, &bStrLeft, &bStrRight, &bStrCenter);

 

       bRetVal = GetSimpleFirstCalcu(bStrCenter, &nLeft, &nRight, &nSignPos);

       if(bRetVal)   //找到了

       {

              FormulaCutCenter(pFormula, nBktLeft+1+nLeft, nBktLeft+1+nRight, &bStrLeft, &bStrRight, &bStrCenter);

 

 

              *pbStrLeft = bStrLeft;

              *pbStrRight = bStrRight;

              *pbStrFirst = bStrCenter;

              *pnFirstSignPos = nSignPos;

              return 1;

       }

 

       //括号内不是运算式, 判断是否是函数

       nRetVal = GetFunsIndex(pFormula, nBktLeft, &nLeft);             //是否为函数

       if(nRetVal == -1)       //不是函数, 只是纯粹是括号

       {

              pCopyFormula = MallocByStr(pFormula);

              StrDel(pCopyFormula, nBktLeft, 1);

              StrDel(pCopyFormula, nBktRight-1, 1);

 

              nRetVal = GetFirstCalcu(pCopyFormula, pbStrLeft, pbStrRight, pbStrFirst, pnFirstSignPos);

              if(nRetVal == 0) //没任何运算操作

              {

                     *pbStrFirst = pCopyFormula;

                     free(pCopyFormula);

                     return -1;

              }

 

              free(pCopyFormula);

              return nRetVal;            //去掉括号递归

       }

 

       //   是函数

       FormulaCutCenter(pFormula, nLeft, nBktRight+1, &bStrLeft, &bStrRight, &bStrCenter);

       *pbStrLeft = bStrLeft;

       *pbStrRight = bStrRight;

       *pbStrFirst = bStrCenter;

       *pnFirstSignPos = nRetVal;

       return 2;

}

 

 

//   判断是否是负号(TRUE), 可能是减号(FALSE)       适合函数 GetSimpleFirstCalcu

BOOL CFormula::IdentifyMinus(CHAR *pFormula, int nPos)

{

       int         i;

       for(i=nPos-1; i>=0; i--)

       {

              if(pFormula[i] == ' ' || pFormula[i] == '/t')

                     continue;

 

              if(GetSignIndex(pFormula, i, NULL) != -1 || pFormula[i] == 'E')

                     return TRUE;

              else

                     return FALSE;

       }

       return TRUE;

}

 

//   判断改括号是否是函数的

int CFormula::GetFunsIndex(CHAR *pFormula, int nBracketPos, int * pFunStart)

{

       int         i;

       CHAR   * pFunName;

 

       for(i=0; ; i++)

       {

              if(Function[i].pFun == NULL)

                     return -1;

 

              if(nBracketPos >= Function[i].nFunNameLen)

              {

                     pFunName = pFormula+nBracketPos-Function[i].nFunNameLen;

                     if(strncmp(Function[i].szFunName, pFunName, Function[i].nFunNameLen) == 0)

                     {

                            *pFunStart = nBracketPos - Function[i].nFunNameLen;

                            return i;

                     }

              }

       }

       return -1;

}

 

BOOL CFormula::GetFirstBracket(CHAR * pFormula, int * pLeftPos, int * pRightPos)

{

       int                i;

 

       for(i=0; ;i++)

       {

              if(pFormula[i] == 0)

                     return FALSE;

              if(pFormula[i] == ')')

                     break;

       }

       *pRightPos = i;

 

       for(i=*pRightPos; ; i--)

       {

              if(i < 0)

                     return FALSE;

              if(pFormula[i] == '(')

                     break;

       }

       *pLeftPos = i;

 

       return TRUE;

}

 

BOOL CFormula::GetSimpleFirstCalcu(CHAR * pFormula, int *pnLeftPos, int *pnRightPos, int *pSignPos)

{

       int                i, nTopSignLev, nCurSignLev, nTopSignIndex, nCurSignIndex;

       BOOL           bRetVal;

       int                nTopPos = -1, nLeftPos, nRightPos;

 

       nTopSignLev = MAX_SIGN_LEVEL;

 

       for(i=0; pFormula[i]!='/0'; i++)          //找到所用运算符, 找最顶级的运算符

       {

              nCurSignIndex = GetSignIndex(pFormula, i, &nCurSignLev);

              if(nCurSignIndex < 0)

                     continue;

 

              if(pFormula[i] == '-' || pFormula[i] == '+')

              {

                     bRetVal = IdentifyMinus(pFormula, i);

                     if(bRetVal)

                            continue;

              }

 

              if(nCurSignLev < nTopSignLev)

              {

                     nTopSignLev = nCurSignLev;

                     nTopSignIndex = nCurSignIndex;

                     nTopPos = i;

              }

       }

 

       if(nTopPos == -1)            //没运算符

              return FALSE;

 

       for(i=nTopPos-1; ; i--)              //左边一个操作符, 后面开始就是

       {

              if(i <= 0)                         //没有就是第一个

              {

                     nLeftPos = 0;

                     break;

              }

 

              if( GetSignIndex(pFormula, i, &nCurSignLev) == -1)

                     continue;

 

              if(pFormula[i] == '-' || pFormula[i] == '+')

              {

                     bRetVal = IdentifyMinus(pFormula, i);

                     if(bRetVal)

                            continue;

              }

 

              nLeftPos = i+1;

              break;

       }

 

       int         nStart;

       nStart = nTopPos + Sign[nTopSignIndex].nSignLen;

 

       for(i=nStart; ; i++)                  //右边一个操作符, 后面开始就是

       {

              if(pFormula[i] == '/0')              //到最后

              {

                     nRightPos = i;

                     break;

              }

 

              if( GetSignIndex(pFormula, i, &nCurSignLev) == -1)

                     continue;

 

              if(pFormula[i] == '-' || pFormula[i] == '+')

              {

                     bRetVal = IdentifyMinus(pFormula, i);

                     if(bRetVal)

                            continue;

              }

 

              nRightPos = i;

              break;

       }

 

       while(pFormula[nLeftPos] == ' ' || pFormula[nLeftPos] == '/t')

       {

              nLeftPos ++;

       };

       while(pFormula[nRightPos-1] == ' ' || pFormula[nRightPos-1] == '/t')

       {

              nRightPos --;

       };

 

       *pnLeftPos = nLeftPos;

       *pnRightPos = nRightPos;

      

       *pSignPos = nTopPos - nLeftPos;

 

       return TRUE;

}

 

 

 

BOOL CFormula::GetResultString(_bstr_t * pbStrError)

{

       return TRUE;

}

 

BOOL CFormula::GetKnowSign(_bstr_t * pbStrSign)

{

       return TRUE;

}

 

BOOL CFormula::GetKnowFunction(_bstr_t * pbStrFunction)

{

       int                i;

       _bstr_t          bStrText;

       for(i=0; ; i++)

       {

              if(Function[i].szFunName[0] == 0)

                     break;

 

              bStrText += Function[i].szFunName;

              bStrText += "/r/n";

       }

       *pbStrFunction = bStrText;

       return TRUE;

}

 

 

CHAR * CFormula::LongDouble2a(long double ldValue, MString *pString)

{

 

       CHAR       szBuf[1024], szRet[1024], szNub[20];

       int         nLev, i;

       CHAR   * pDot, * pLev, * pStr;

       int         nDig = 19;

 

       if(nDig > 20)

              nDig = 14;

 

       nDig --;

       sprintf(szBuf, "%.*E", nDig, ldValue);

       pLev = strchr(szBuf, 'E');

       pDot = strchr(szBuf, '.');

       if(pLev == NULL || pDot == NULL)

       {

              *pString = "Error!";

              return *pString;

       }

       nLev = atoi(pLev+1);

       pLev[0] = 0;

       if(nLev == 0)

       {

              StrTrimRight(szBuf, '0');

              StrTrimRight(szBuf, '.');

              *pString = szBuf;

              return *pString;

       }

 

       strcpy(szRet, "");

       pStr = szBuf;

       if(*pStr == '-')

       {

              pStr ++;

              strcpy(szRet, "-");

       }

 

       pDot[0] = 0;

       strcpy(szNub, pStr);

       strcat(szNub, pDot+1);

 

       if(nLev < 0)

       {

              strcat(szRet, "0.");

              for(i=0; i>nLev+1; i--)

                     strcat(szRet, "0");

              strcat(szRet, szNub);

              StrTrimRight(szRet, '0');

              StrTrimRight(szRet, '.');

       }

       else if(nLev > 0)

       {

              CHAR       szInt[20];

              if(nLev > nDig)

              {

                     strcat(szRet, szNub);

                     for(i=nDig; i<nLev; i++)

                            strcat(szRet, "0");

              }

              else

              {

                     strncpy(szInt, szNub, nLev+1);

                     szInt[nLev+1] = 0;

                     strcat(szRet, szInt);

                     strcat(szRet, ".");

                     strcat(szRet, szNub+nLev+1);

                     StrTrimRight(szRet, '0');

                     StrTrimRight(szRet, '.');

              }

 

       }

       *pString = szRet;

       return *pString;

 

}

 

 

 

long double CFormula::a2LongDouble(CHAR *pString)

{

       int                       i;

       long double         dwValue;

       double                dValue;

 

       for(i=0; ; i++)

       {

              if(pString[i] != '/t' && pString[i] != ' ' && pString[i] != '/0')

                     break;

       }

       pString += i;

 

       if(pString[0] == '0' && (pString[1] == 'x' || pString[1] == 'X'))

       {

              dwValue = strtoul(pString, NULL, 16);

              return((double)dwValue);

       }

 

       dValue = atof(pString);

       if(strstr(pString, ".#INF"))

       {

              int                x = 0;

              dValue = 1 / (double)x;

       }

 

       return dValue;

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值