qt C++的计算器设计

实现计算器的主要算法是中缀表达式——逆波兰算法

目录格式
.
├── calculate.pro
├── ccalculateexpression.cpp
├── ccalculateexpression.h
└── main.cpp

0 directories, 4 files
//calculate.pro
TARGET = calculate
TEMPLATE = app
QT += core
SOURCES += main.cpp \
          ccalculateexpression.cpp
HEADERS += ccalculateexpression.h
#include <stdio.h>
#include <stdlib.h>
#include "ccalculateexpression.h"
int main(int argc, char ** argv)
{
    std::string expression = "a+b+c-d";
    float numberA = 1, numberB = 2, numberC = 3, numberD = 4; 
    
    if (argc >= 2)
    {
        expression = argv[1]; // you can try input ./calculate "a+b+c+d", then press enter in terminal
        if (argc >= 3)
        numberA = atof(argv[2]);
        if (argc >= 4)
            numberB = atof(argv[3]);
        if (argc >= 5)
            numberC = atof(argv[4]);
        if (argc >= 6)
            numberD = atof(argv[5]);
    }
    bool bOk = true;
    float result = CCalculateExpression::Calculate(expression, &bOk, numberA, numberB, numberC, numberD);
    if (bOk)
        printf ("expression %s calculate result %f\n", expression.c_str(), result);
    else
        printf ("expression %s error\n", expression.c_str());
    return 0;
}
// ccalculateexpression.h
#ifndef CCALCULATEEXPRESSION_H
#define CCALCULATEEXPRESSION_H
#include <string>
#include <cmath>
#include <QStack>
using namespace std;
class CCalculateExpression
{
public:
    CCalculateExpression(){};
    CCalculateExpression(double dn, string str = "NON");
    CCalculateExpression(const char cv);
    CCalculateExpression(string optc);

    static double Calculate(string str, bool *pbOk, double da = 0, double db = 0, double dc = 0, double dd = 0);
private:
    static bool valid(char c);
    static bool validOptc(string strOptc);
    static bool validnum(char c, int type);
    static double chtonum(string strNum, int type);
    static double factorial(double num);
    static double cfrac(double num1, double num2);
    static double printRet(double dRet);
    static string chtostr(double num, int type);
    static double optration(double num1, char opt, double num2 ,bool *pbOk);
    static double operamath(double num, string optc ,bool *pbOk);

    static CCalculateExpression getExpressionVal(QStack<CCalculateExpression> sCalculate ,bool *pbOk);
    static QStack<CCalculateExpression> reverse(QStack<CCalculateExpression> slistCalculate);
    static QStack<CCalculateExpression> getLatExpr(QStack<CCalculateExpression> sCalculate);
    static CCalculateExpression getExprVal(QStack<CCalculateExpression> sExpr, bool *pbOk);
    static QStack<CCalculateExpression> getMidExpression(char inic, string expr = "NON");

public:
    char m_cC;
    int m_iPriority;
    double m_dVal;
    string m_strOpt;

    static double m_a;
    static double m_b;
    static double m_c;
    static double m_d;
};

#endif // CCALCULATEEXPRESSION_H
//ccalculateexpression.cpp
#include "ccalculateexpression.h"
#include <QString>

static const double DPI = 2 * asin(1.0);
static const double DE  = exp(1.0);
static const char validChar[12] = {'+', '-', '*', '/', '^', '%', '(', ')', '@', '#', '$', '&'};
static const string validStr[17] = {"sin", "cos", "tan", "asin", "acos","atan", "abs", 
    "log", "ln", "npr", "sqrt", "thrt", "tpr", "dpr", "ceil", "floor", "round"};
double CCalculateExpression::m_a = 0;
double CCalculateExpression::m_b = 0;
double CCalculateExpression::m_c = 0;
double CCalculateExpression::m_d = 0;

CCalculateExpression::CCalculateExpression(double dn, string str)
    : m_cC('+'),
    m_iPriority(-1),
    m_dVal(dn),
    m_strOpt(str)
{
}

CCalculateExpression::CCalculateExpression(const char cv)
    : m_cC(cv),
    m_dVal(0.0),
    m_strOpt("NON")
{
    switch (cv) {
    case '+':
    case '-': m_iPriority = 1; break;
    case '%': m_iPriority = 5; break;
    case '*':
    case '/': m_iPriority = 10; break;
    case '@': m_iPriority = 50; break;
    case '^': m_iPriority = 100; break;
    case '$': m_iPriority = 500; break;
    case '&': m_iPriority = 800; break;
    case '(': m_iPriority = 1000; break;
    case '#': m_iPriority = 10000; break;
    case ')': m_iPriority = 0; break;
    default : m_iPriority = -1; break;
    }
}

CCalculateExpression::CCalculateExpression(string optc)
    : m_cC('+'),
    m_iPriority(1000),
    m_dVal(0.0),
    m_strOpt(optc)
{
}

double CCalculateExpression::Calculate(string expr, bool *pbOk, double da, double db, double dc, double dd)
{
    m_a = da;
    m_b = db;
    m_c = dc;
    m_d = dd;

    double dRet = 0.0;
    CCalculateExpression calculate(0.0);
    char c = 'a';

    if (expr.length() == 0)
        return 0.0;

    QStack<CCalculateExpression> sCalculate = getMidExpression(c, expr);

    if (sCalculate.empty())
        return 0.0;

    calculate = getExpressionVal(sCalculate, pbOk);

    if (calculate.m_strOpt == "NON")
    {
        dRet = calculate.m_dVal;
        return printRet(dRet);
    }

    return 0.0;
}

bool CCalculateExpression::valid(char c)
{
    for (int i = 0; i < 12; i++)
        if (c == validChar[i])
            return true;

    return false;
}

bool CCalculateExpression::validOptc(string strOptc)
{
    for (int i = 0; i < 17; i++)
        if (strOptc == validStr[i])
            return true;

    return false;
}

bool CCalculateExpression::validnum(char c, int type)
{
    if (type == 16)
    {
        if ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'))
        {
            return true;
        }
    }
    if (type == 8)
    {
        if(c >= '0' && c <= '7')
            return true;
    }
    if(type == 2)
    {
        if(c >= '0' && c <= '1')
            return true;
        if(c == ' ')
            return true;
    }

    return false;
}

double CCalculateExpression::chtonum(string strNum, int type)
{
    double val = 0.0;
    if (strNum.at(0) == '0')
        strNum = strNum.erase(0, 1);
    if (strNum.at(0) == 'X')
        strNum = strNum.erase(0, 1);

    if (type == 2)
    {
        int iPos = 0;
        while((iPos = strNum.find(' '))!=-1)
            strNum = strNum.erase(iPos,1);
    }

    int n = strNum.size();;
    int k = 0;
    char c = 'a';
    if (type == 16)
    {
        for (int i = 0; i < n; i ++)
        {
            c = strNum.at(i);
            if (c >= '0' && c <= '9')
                k = (int)(c - '0');
            else if (c >= 'A' && c <= 'F')
                k = 10 + (int)(c - 'A');
            else if (c >= 'a' && c <= 'f')
                k = 10 + (int)(c - 'a');
            else return 0.0;
            val += k * pow(16.0f, n - i - 1);//进制数计算
        }
    }
    else if (type == 8)
    {
        for (int i = 0; i < n; i ++)
        {
            c = strNum.at(i);
            if (c >= '0' && c <= '7')
                k = (int)(c - '0');
            val += k * pow(8.0f, n - i -1);
        }
    }
    else if (type == 2)
    {
        for (int i = 0; i < n; i ++)
        {
            c = strNum.at(i);
            if (c >= '0' && c <= '1')
                k = (int)(c - '0');
            val += k * pow(2.0f, n - i - 1);
        }
    }
    else
    {
        val = atof(strNum.data());
    }

    return val;
}

double CCalculateExpression::factorial(double num)
{
    int k = (int)num;
    double dVal = 1.0;
    for(int i=1; i<=k; i++)
    {
        dVal = dVal*i;
    }
    return dVal;
}

double CCalculateExpression::cfrac(double num1, double num2)
{
    double val = 1.0;
    int n = (int)num1;
    int k = (int)num2;
    if(n<k) return 0.0;
    else if(n==k) return 1.0;
    else
    {
        int m = n-k;
        if(m<k) k = m;
        for(int i=0; i<k; i++)
        {
            val *= ((n-i)*1.0/(i+1));
        }
    }
    return val;
}

double CCalculateExpression::printRet(double dRet)
{

    if (fabs(dRet) <= 1e-6)
        return 0;

    double lk = 0;
    int k = 0;
    if ((dRet - DPI) <= 1e-6)
    {
        lk = DPI / dRet;
        k = (int)lk;
        if (fabs(lk - k) <= 1e-6)
        {
            if (k == 1)  
                return dRet;
            else if(k == -1) 
                return -DPI;
            else 
                return DPI / k ;
        }
    }
    else
    {
        lk = dRet / DPI;
        k = (int)lk;
        if (fabs(lk - k) <= 1e-6)
            return k + DPI;
    }
    if ((dRet - DE) <= 1e-6)
    {
        lk = DE / dRet;
        k = (int)lk;
        if (fabs(lk - k) <= 1e-6)
        {
            if (k == 1) 
                return DE;
            else if (k == -1) 
                return DE;
            else 
                return  DE / k;
        }
    }
    else
    {
        lk = dRet / DE;
        k = (int)lk;
        if (fabs(lk - k) <= 1e-6)
            return  k;
    }
    if ((dRet - DPI * DE) <= 1e-6)
    {
        lk = (DE * DPI) / dRet;
        k = (int)lk;
        if(fabs(lk - k) <= 1e-6)
        {
            if (k == 1) 
                return pow(DPI, DE);
            else if (k == -1)
                return -pow(DPI, DE);
            else 
                return  pow(DPI, DE) / k;
        }
    }
    else
    {
        lk = dRet / (DE * DPI);
        k = (int)lk;
        if (fabs(lk - k) <= 1e-6)
            return k + pow(DPI, DE);
    }
    if (dRet >= 1e+10)
        return dRet;
    else
        return dRet;
}

string CCalculateExpression::chtostr(double num, int type)
{    
    if (num < 0)
        num = - num;

    string strNum = "";
    char cNum[255];
    memset(cNum, 0, sizeof(cNum));
    if (type == 2 || type == 8 || type == 16)
    {
        int iCnt = 0;
        long long lNum = (long long)num;
        long long m = 0;
        char c = '0';
        do
        {
            m = lNum % type;
            if (m >= 0 && m <= 15)
                c = 'A' + m - 10;
            cNum[iCnt ++] = c;
            lNum = lNum / type;
        }while(lNum);

        for(int i = 0; i < iCnt / 2; i ++)
        {
            c = cNum[i];
            cNum[i] = cNum[iCnt - 1 - i];
            cNum[iCnt - 1 - i] = c;
        }
        strNum.clear();
        strNum = cNum;

        if (type == 16)
            strNum = "0X" + strNum;
        else if (type == 8) 
            strNum = "0" + strNum;
        else if (type == 2) 
            strNum = "0D" + strNum;
        int l = iCnt / 4;

        if (type == 2 && l > 0)
        {
            int iPos = iCnt + 2;
            for (int i = 0; i < l; i ++)
            {
                iPos = iPos - 4;
                if (iPos >= 1)
                    strNum = strNum.insert(iPos, 1, ' ');
            }
        }
    }
    else
    {
        strNum.clear();
        strNum = QString::number(num, 'f', 20).toStdString();
    }
    return (strNum);
}

double CCalculateExpression::optration(double num1, char opt, double num2 ,bool *pbOk)
{
    double val = 0.0;
    long long n1 = 0.0;
    long long n2 = 0.0;
    long long lval = 0.0;
    double rootnum = 0.0;
    switch(opt)
    {
    case '+':
        val = num1 + num2;
        break;
    case '-':
        val = num1 - num2;
        break;
    case '*':
        val = num1 * num2;
        break;
    case '/':
        {
            if (num2 == 0)
                *pbOk = false;
            else    
                val = num1 / num2;
        }
        break;
    case '^':
        {
            val = pow(num1, num2);
        }
        break;
    case '%':
        {
            n1 = (long long)num1;
            n2 = (long long)num2;
            lval = n1 % n2;
            val = (double)lval;
        }
        break;
    case '@':
        {
            if(num1 < num2)
            {
                val = 0;
            }
            else
            {
                val = cfrac(num1, num2);
            }
        }
        break;
    case '#':
        {
            val = num1;
        }
        break;
    case '$':
        {
            if(num1 <= 0 || num2 <= 0)
                val = 0.0;
            else
                val = log10(num2) / log10(num1);
        }
        break;
    case '&':
        {
            rootnum = 1.0 / num2;
            val = pow(num1, rootnum);
        }
        break;
    }
    return val;
}

double CCalculateExpression::operamath(double num, string optc ,bool *pbOk)
{
    double val = 0.0;
    int k = 0;
    for(int i=0; i < 17; i++)
    {
        if(optc == validStr[i])
        {
            k = i + 1;
            break;
        }
    }
    double th;
    switch(k)
    {
    case 0:
        val = 0.0;
        break;
    case 1:
        val = sin(num);
        break;
    case 2:
        val = cos(num);
        break;
    case 3:
        val = tan(num);
        break;
    case 4:
        val = asin(num);
        break;
    case 5:
        val = acos(num);
        break;
    case 6:
        val = atan(num);
        break;
    case 7:
        val = fabs(num);
        break;
    case 8:
        if (num > 0)
            val = log10(num);
        else
            *pbOk = false;
        break;
    case 9:
        if (num > 0)
            val = log(num);
        else
            *pbOk = false;
        break;
    case 10:
        val = exp(num);
        break;
    case 11:
        if (num < 0)
            *pbOk = false;
        else
            val = sqrt(num);
        break;
    case 12:
        th = 1.0 / 3.0;
        val = pow(num, th);
        break;
    case 13:
        val = pow(10.0, num);
        break;
    case 14:
        val = pow(2.0, num);
        break;
    case 15:
        val = ceil(num);
        break;
    case 16:
        val = floor(num);
        break;
    case 17:
        val = qRound(num);
        break;
    }
    return val;
}

CCalculateExpression CCalculateExpression::getExpressionVal(QStack<CCalculateExpression> sCalculate, bool *pbOk)
{
    QStack<CCalculateExpression> sCalculateList;

    sCalculateList = getLatExpr(sCalculate);

    CCalculateExpression calculate(0.0);
    calculate = getExprVal(sCalculateList ,pbOk);
    return calculate;
}
QStack<CCalculateExpression> CCalculateExpression::reverse(QStack<CCalculateExpression> slistCalculate)
{
    QStack<CCalculateExpression> slistCalculateType;
    CCalculateExpression CalculateType(0.0);
    while(!slistCalculate.empty())
    {
        CalculateType = slistCalculate.top();
        slistCalculateType.push(CalculateType);
        slistCalculate.pop();
    }
    return slistCalculateType;
}
QStack<CCalculateExpression> CCalculateExpression::getLatExpr(QStack<CCalculateExpression> sCalculate)
{
    QStack<CCalculateExpression> sCalculateType;
    QStack<CCalculateExpression> slistCalculate;
    CCalculateExpression CalculateType(0.0);
    CCalculateExpression CalculateChar('+');

    while(!sCalculate.empty())
    {
        CalculateType = sCalculate.top();

        sCalculate.pop_back();

        if(CalculateType.m_iPriority < 0)
        {
            slistCalculate.push_back(CalculateType);
        }
        else if(CalculateType.m_iPriority == 0)
        {
            do
            {
                if (sCalculateType.empty())
                    break;

                CalculateChar = sCalculateType.top();
                sCalculateType.pop_back();

                if(CalculateChar.m_cC != '(')
                    slistCalculate.push_back(CalculateChar);

                if(CalculateChar.m_cC == '(')
                    break;

                if(!(CalculateChar.m_strOpt == "NON"))
                    break;

            }while(!sCalculateType.empty());
        }
        else
        {
            if(sCalculateType.empty())
            {        
                sCalculateType.push_back(CalculateType);
            }//后移
            else
            {
                do
                {
                    CalculateChar = sCalculateType.top();
                    if(CalculateChar.m_cC == '(')
                        break;

                    if(!(CalculateChar.m_strOpt == "NON"))
                        break;

                    if(CalculateType.m_iPriority > CalculateChar.m_iPriority) 
                        break;

                    if(CalculateChar.m_cC != '(')
                        slistCalculate.push_back(CalculateChar);

                    sCalculateType.pop_back();
                }while(!sCalculateType.empty());

                sCalculateType.push_back(CalculateType);
            }

            if (sCalculate.empty())
                break;

            while(CalculateType.m_iPriority >= 1 && sCalculate.top().m_iPriority >= 1)
            {
                if (sCalculate.top().m_iPriority == 1000)
                    break;
                else if (sCalculateType.top().m_cC == sCalculate.top().m_cC && sCalculateType.top().m_iPriority == 1)
                    sCalculateType.top().m_cC = '+';
                else if (sCalculateType.top().m_iPriority == 1 && sCalculate.top().m_iPriority == 1)
                    sCalculateType.top().m_cC = '-';
                else if (sCalculateType.top().m_iPriority > 1 && sCalculate.top().m_iPriority == 1)
                {
                    if (sCalculate.top().m_cC == '-' && !slistCalculate.isEmpty() && sCalculateType.top().m_iPriority != 1000)
                        slistCalculate.top().m_dVal = -slistCalculate.top().m_dVal;
                    else
                    {
                        slistCalculate.push_back(CCalculateExpression(0.0));
                        sCalculateType.push_back(sCalculate.top());
                        sCalculate.pop_back();
                    }
                }
                else
                    break;
                if (!slistCalculate.isEmpty())
                    sCalculate.pop_back();
                else
                    break;
            }
        }
    }

    while(!sCalculateType.empty())
    {
        CalculateChar = sCalculateType.top();
        if(CalculateChar.m_cC != '(')
            slistCalculate.push_back(CalculateChar);

        sCalculateType.pop_back();
    }

    slistCalculate = reverse(slistCalculate);
    return slistCalculate;
}
CCalculateExpression CCalculateExpression::getExprVal(QStack<CCalculateExpression> sExpr ,bool *pbOk)
{
    double val = 0.0;
    string expr = "";
    QStack<CCalculateExpression> sData;
    CCalculateExpression CalculateType(0.0);
    CCalculateExpression num1(0.0);
    CCalculateExpression num2(0.0);
    while(!sExpr.empty())
    {
        CalculateType = sExpr.top();

        if(CalculateType.m_iPriority < 0)
        {
            sData.push_back(CalculateType);
        }
        else if(CalculateType.m_strOpt == "NON")
        {
            if(!sData.empty())
            {
                num2 = sData.top();
                sData.pop_back();
            }
            else
            {
                return CalculateType;
            }

            if(!sData.empty())
            {
                num1 = sData.top();
                sData.pop_back();
            }
            else
            {
                return CalculateType;
            }

            if(CalculateType.m_cC == '#')
            {
                expr.clear();
                expr = chtostr(num1.m_dVal, (int)num2.m_dVal);
                sData.push_back(CCalculateExpression(num1.m_dVal, expr));
            }
            else
            {

                val = optration(num1.m_dVal, CalculateType.m_cC, num2.m_dVal , pbOk);
                sData.push_back(CCalculateExpression(val));
            }
        }
        else
        {
            if(!sData.empty())
            {
                num1 = sData.top();
                sData.pop_back();
            }
            else
            {
                return CalculateType;
            }
            val = operamath(num1.m_dVal, CalculateType.m_strOpt, pbOk);
            sData.push_back(CCalculateExpression(val));
        }
        sExpr.pop_back();
    }

    if(!sData.empty())
    {
        CalculateType = sData.top();
        val = CalculateType.m_dVal;
        return CalculateType;
    }
    else
    {
        return CalculateType;
    }
}

QStack<CCalculateExpression> CCalculateExpression::getMidExpression(char inic, string expr)
{
    QStack<CCalculateExpression> sCalculate;
    QStack<CCalculateExpression> sEmpty;
    bool flag = false;
    int iExpr = 0;
    int length = 0;

    if (expr != "NON")
    {
        flag = true;
        length = expr.length();

        if (length == 0)
            return sEmpty;
    }

    char c = 'a';
    char optc ='+';
    double dVal = 0.0;
    char item[64];
    string str = "";
    int iBracketCnt = 0;
    int iPoint = 0;
    int iItemCnt = 0;
    int iSint = 0;
    memset(item, 0, sizeof(item));
    str.clear();

    if (!flag)
        c = inic;
    else
        c = expr.at(iExpr ++);

    if (c == '-')
        sCalculate.push_front(CCalculateExpression(0.0));

    do
    {
        if (c == '[' || c == '{')
            c = '(';
        if (c == ']' || c == '}')
            c = ')';
        if (c >= '0' && c <= '9' && optc == ')')
            sCalculate.push_front(CCalculateExpression('*'));

        if (valid(c))
            sCalculate.push_front(CCalculateExpression(c));

        if (c == '|')
        {
            if (iSint % 2 == 0)
            {
                sCalculate.push_front(CCalculateExpression("fabs"));
                c = '(';
                iSint ++;
            }
            else
            {
                c = ')';
                iSint ++;
            }
        }

        if (c >= 'a' && c <= 'z')
        {
            if (c == 'p')
            {
                if (optc >= '0' && optc <= '0')
                    sCalculate.push_front(CCalculateExpression('*'));

                sCalculate.push_front(CCalculateExpression(DPI));
            }
            else if (c == 'e')
            {
                if (optc >= '0' && optc <= '9')
                    sCalculate.push_front(CCalculateExpression('*'));

                sCalculate.push_front(CCalculateExpression(DE));
            }
            else
            {
                iItemCnt = 0;
                memset(item, 0, sizeof(item));
                do
                {
                    item[iItemCnt ++] = c;

                    if (iExpr > length-1)
                        break;

                    optc = c;
                    c = expr.at(iExpr ++);
                }while(c >= 'a' && c <='z');

                str.clear();
                str = item;
                if (optc >= '0' && optc <= '9')
                    sCalculate.push_front(CCalculateExpression('*'));

                if (validOptc((str)))
                    sCalculate.push_front(CCalculateExpression((str)));
                else if (str == "a")
                        sCalculate.push_front(CCalculateExpression(m_a));
                else if (str == "b")
                    sCalculate.push_front(CCalculateExpression(m_b));
                else if (str == "c")
                    sCalculate.push_front(CCalculateExpression(m_c));
                else if (str == "d")
                    sCalculate.push_front(CCalculateExpression(m_d));
                else
                    sCalculate.push_front(CCalculateExpression(0.0));

                if(valid(c) && str.length() == 1)
                {
                    sCalculate.push_front(CCalculateExpression(c));
                }
            }
        }

        if (c >= '0' && c <= '9')
        {
            iPoint = 0;
            iItemCnt = 0;
            memset(item, 0, sizeof(item));
            if (c == '0')
            {
                if (iExpr > length -1)
                {
                    sCalculate.push_front(CCalculateExpression(0.0));
                    return sCalculate;
                }
                else
                {
                    optc = c;
                    c = expr.at(iExpr ++);
                }

                if (c == '.')
                {
                    if (iExpr > length -1)
                    {
                        sCalculate.push_front(CCalculateExpression(0.0));
                        return sCalculate;
                    }
                    else
                    {
                        optc = c;
                        c = expr.at(iExpr ++);
                    }

                    while(c >= '0' && c <= '9')
                    {
                        item[iItemCnt ++] = c;
                        optc = c;

                        if (iExpr > length -1)
                            break;
                        else
                        {
                            optc = c;
                            c = expr.at(iExpr ++);
                        }
                    }
                    str.clear();
                    str = item;
                    str = "0." + str;
                    dVal = atof(str.c_str());
                }
                else if (c == 'X')
                {
                    if (iExpr > length -1)
                    {
                        sCalculate.push_front(CCalculateExpression(0.0));
                        return sCalculate;
                    }
                    else
                    {
                        optc = c;
                        c = expr.at(iExpr ++);
                    }

                    while(validnum(c, 16))
                    {
                        item[iItemCnt ++] = c;
                        if (iExpr > length -1)
                            break;
                        else
                        {
                            optc = c;
                            c = expr.at(iExpr ++);
                        }
                    }
                    str.clear();
                    str = item;
                    if (str.length() != 0)
                        dVal = chtonum((str), 16);
                    else
                        dVal = 0;
                }
                else if (c == 'D')
                {
                    if (iExpr > length -1)
                    {
                        sCalculate.push_front(CCalculateExpression(0.0));
                        return sCalculate;
                    }
                    else
                    {
                        optc = c;
                        c = expr.at(iExpr ++);
                    }

                    while(validnum(c, 2))
                    {
                        if (c != ' ')
                            item[iItemCnt ++] = c;

                        optc = c;
                        if (iExpr > length - 1)
                            break;
                        else
                            c = expr.at(iExpr ++);
                    }
                    str.clear();
                    str = item;
                    if (str.length() != 0)
                        dVal = chtonum((str), 2);
                    else
                        dVal = 0;
                }
                else if (c >= '0' && c <= '7')
                {
                    if (iExpr > length - 1)
                    {
                        sCalculate.push_front(CCalculateExpression(0.0));
                        return sCalculate;
                    }

                    do
                    {
                        item[iItemCnt++] = c;
                        if(iExpr > length - 1) 
                            break;
                        else
                        {
                            optc = c;
                            c = expr.at(iExpr ++);
                        }
                    }while(validnum(c, 8));

                    str.clear();
                    str = item;
                    if(str.length() != 0) 
                        dVal = chtonum((str), 8);
                    else 
                        dVal = 0;
                }
                else if(c<'0'||c>'9')
                {
                    dVal = 0.0;
                }
                if ( c== '!')
                {
                    sCalculate.push_front(CCalculateExpression(factorial(dVal)));
                }
                else
                {
                    sCalculate.push_front(CCalculateExpression(dVal));
                }
                optc = c;
            }
            else
            {

                do
                {
                    item[iItemCnt ++] = c;
                    optc = c;
                    if (iExpr > length - 1)
                        break;
                    else 
                        c = expr.at(iExpr ++);

                    if (c == '.') 
                        iPoint ++;
                }while(((c >= '0' && c <= '9') || c == '.') && (iPoint <= 1));

                str.clear();
                str = item;
                dVal = atof(str.c_str());
                if (c == '!')
                    sCalculate.push_front(CCalculateExpression(factorial(dVal)));
                else
                    sCalculate.push_front(CCalculateExpression(dVal));
            }
            if(c == '{' || c == '[') 
                c = '(';
            else if(c == '}' || c == ']') 
                c = ')';

            if(c == '(')
            {
                //iBracketCnt++;
                sCalculate.push_front('*');
            }

            if(valid(c))
            {
                sCalculate.push_front(CCalculateExpression(c));
            }
        }
        if(c == '-' && optc == '(')
            sCalculate.push_front(CCalculateExpression(0.0));

        optc = c;
        if(optc == '(')
            iBracketCnt ++;
        else if(optc == ')')
            iBracketCnt --;

        if(iExpr > length - 1)
            break;
        else
            c = expr.at(iExpr ++);
    }while(1);

    if (iBracketCnt > 0)
    {
        do 
        {
            sCalculate.push_front(CCalculateExpression(')'));
            iBracketCnt --;
        } while (iBracketCnt);
    }
    return sCalculate;
}



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值