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

📄 calcengine.cpp

📁 大学时用c++做的计算器
💻 CPP
字号:
#include "calcengine.h"#include <cctype>#include <cmath>#include <algorithm>CalculatorEngine::FunctionMapType CalculatorEngine::__funcTable;void CalculatorEngine::buildFunctionTable(){    __funcTable["sin"] = &Function::Sin;    __funcTable["cos"] = &Function::Cos;    __funcTable["tan"] = &Function::Tan;    __funcTable["asin"] = &Function::Asin;    __funcTable["acos"] = &Function::Acos;    __funcTable["atan"] = &Function::Atan;    __funcTable["sinh"] = &Function::Sinh;    __funcTable["cosh"] = &Function::Cosh;    __funcTable["tanh"] = &Function::Tanh;    __funcTable["asinh"] = &Function::Asinh;    __funcTable["acosh"] = &Function::Acosh;    __funcTable["atanh"] = &Function::Atanh;    __funcTable["exp"] = &Function::Exp;    __funcTable["ln"] = &Function::Ln;    __funcTable["log"] = &Function::Log;    __funcTable["sqrt"] = &Function::Sqrt;    __funcTable["fct"] = &Function::Fct;}CalculatorEngine::CalculatorEngine(){    __token = PRINT;    __number = 0;        __table["pi"] = Pi;    __table["PI"] = Pi;    __table["e"] = E;    __inStream.str("");    buildFunctionTable();}void CalculatorEngine::pushIdentifier(const std::string& name, const ValueType& value){    if (name == std::string("pi") || name == std::string("Pi") ||        name == std::string("e"))        throw InvalidAssignment();    __table[name] = value;}void CalculatorEngine::setRDState(CalculatorEngine::RDState s){    __func.__state = s;}void CalculatorEngine::setExpression(const std::string& expr){    __inStream.clear();    __inStream.str(expr);}ValueType CalculatorEngine::calculate(){    ValueType result;    checkParenthesis();    while (__inStream) {        getToken();        if (__token == END) break;        if (__token == PRINT) continue;        result = expr(false);    }        if (result >= Maximum)        throw TooLarge();    return result;}ValueType CalculatorEngine::expr(bool get){    ValueType left = term1(get);        for (;;)        switch (__token) {            case PLUS:                left += term1(true);                break;            case MINUS:                left -= term1(true);                break;            default:                return left;        }}ValueType CalculatorEngine::term1(bool get){    ValueType left = term2(get);        for (;;)        switch (__token) {            case MUL:                left *= term2(true);                break;            case DIV:                if (ValueType d = term2(true)) {         // nonzero                    left /= d;                    break;                }                throw ZeroDivide();                break;            case MOD:                if (ValueType d = term2(true)) {                    left = (long long)(left) % (long long)(d);                    break;                }                throw ZeroDivide();                break;            default:                return left;        }}ValueType CalculatorEngine::term2(bool get){    ValueType left = prim(get);        for (;;)        switch (__token) {			case POW:			{   ValueType e = expr(true);			    if ((left == 0 && e <= 0) || (left < 0 && floor(e) != e))			        throw PowerError();				left = pow(left, e);				break;			}			default:				return left;		}}ValueType CalculatorEngine::prim(bool get){    if (get)        getToken();    switch (__token) {        case NUMBER:        {   ValueType v = __number;            getToken();            if (__token == NAME) {                if (isFunction())                    return v * unaryFunction();                else {                    getToken();                    return v * __table[__string];                }            }            return v;        }        case NAME:        {            if (isFunction()) {                ValueType v = unaryFunction();                return v;            }            else {                ValueType& v = __table[__string];                getToken();                if (__token == ASSIGN) {                    if (__string == std::string("pi") ||                        __string == std::string("PI") || __string == std::string("e"))                        throw InvalidAssignment();                    v = expr(true);                }                return v;            }        }        case MINUS:            return -prim(true);        case LP:        {   ValueType e = expr(true);            if (__token != RP)                throw RightParenMismatch();            getToken();    // eat ')'            return e;        }        default:            throw PrimaryMissing();            return 1;    }}                void CalculatorEngine::getToken(){    char ch;        do {    // skip whitespace except '\n'        if (!__inStream.get(ch)) {            __token == END;            return;        }    } while (ch != '\n' && isspace(ch));    switch (ch) {        case ';':        case '\n':            __token = PRINT;            break;        case '+': case '-': case '*': case '/': case '%':        case '^': case '(': case ')': case '=':            __token = Token(ch);            break;        case '0': case '1': case '2': case '3': case '4':        case '5': case '6': case '7': case '8': case '9':        case '.':            __inStream.putback(ch);            __inStream >> __number;            __token = NUMBER;            break;        default:      // NAME, NAME=, or error            if (isalpha(ch)) {                __string = ch;                while (__inStream.get(ch) && isalnum(ch)) __string.push_back(ch);                __inStream.putback(ch);                __token = NAME;                break;            }            __token = PRINT;            throw BadToken();    }}bool CalculatorEngine::isFunction() const{    if (__funcTable.find(__string) != __funcTable.end())        return true;    else        return false;}ValueType CalculatorEngine::unaryFunction(){    std::string funcName = __string;        getToken();    if (__token != LP)        throw ParenMissing(__string.c_str());    ValueType v = expr(true);    if (__token != RP)        throw RightParenMismatch();    getToken();        return (__func.*__funcTable[funcName])(v);}void CalculatorEngine::checkParenthesis(){	std::string expression = __inStream.str();		int numLP = std::count(expression.begin(), expression.end(), '(');	int numRP = std::count(expression.begin(), expression.end(), ')');		if (numLP < numRP)	    throw LeftParenMismatch();	else if (numRP < numLP)	    throw RightParenMismatch();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -