📄 calculator.cpp
字号:
/* * * * */#include <iostream>#include <cstdlib>#include <cmath>#include "builtin.h"#include "math.h"#include "logic.h"#include "advmath.h"#include "calculator.h"#include "exception.h"using namespace std;//////Item * AutoNumerical(double x){ double ni = nearbyint(x); if (fabs(ni-x) < fabs(1E-10 * x)) return new Integer(long(x)); return new Real(x); }//////Calculator::Calculator() { }//////Calculator::~Calculator() { }//////void Calculator::ApplyZeroArity(Operation p){ Item *r = NULL; switch(p.code) { case CLR: stack.Clear(); break; case TRUE: r = new Logical(true); break; case FALSE: r = new Logical(false); break; case PI: r = new Real(3.1415926535897932); break; case E: r = new Real(2.7182818284590452); break; case PHI: r = new Real(1.6180339887498949); break; case RAND: r = new Real(drand48()); break; case SCI: cout << scientific; break; case FIX: cout << fixed; break; case DEC: stack.SetDisplayMode(DM_DEC); break; case HEX: stack.SetDisplayMode(DM_HEX); break; case OCT: stack.SetDisplayMode(DM_OCT); break; default: break; }; if (r != NULL) stack.Push(r);}//////void Calculator::ApplyUnary(Operation p){ Item *r = NULL; switch(p.code) { case DUP: stack.Duplicate(); break; case DROP: stack.Drop(); break; case RCL: r = varlist.Retrieve(stack.PopString()); break; case ABS: r = AutoNumerical(fabs(stack.PopDouble())); break; case SGN: r = AutoNumerical(sign(stack.PopDouble())); break; case CEIL: r = new Integer(long(ceil(stack.PopDouble()))); break; case FLOOR: r = new Integer(long(floor(stack.PopDouble()))); break; case ROUND: r = new Integer(long(round(stack.PopDouble()))); break; case INV: r = AutoNumerical(1.0/stack.PopDouble()); break; case SQR: r = AutoNumerical(pow(stack.PopDouble(), 2)); break; case SQRT: r = AutoNumerical(sqrt(stack.PopDouble())); break; case CBRT: r = AutoNumerical(cbrt(stack.PopDouble())); break; case EXP: r = AutoNumerical(exp(stack.PopDouble())); break; case EXP10: r = AutoNumerical(exp10(stack.PopDouble())); break; case EXP2: r = AutoNumerical(exp2(stack.PopDouble())); break; case ERF: r = AutoNumerical(erf(stack.PopDouble())); break; case ERFC: r = AutoNumerical(erfc(stack.PopDouble())); break; case SIGMOID: r = AutoNumerical(1.0/(1.0+exp(-stack.PopDouble()))); break; case GAMMA: r = AutoNumerical(tgamma(stack.PopDouble())); break; case FACT: r = AutoNumerical(factorial(long(stack.PopInteger()))); break; case LN: r = AutoNumerical(log(stack.PopDouble())); break; case LOG: r = AutoNumerical(log10(stack.PopDouble())); break; case LOG2: r = AutoNumerical(log2(stack.PopDouble())); break; case J0: r = AutoNumerical(j0(stack.PopDouble())); break; case J1: r = AutoNumerical(j1(stack.PopDouble())); break; case Y0: r = AutoNumerical(y0(stack.PopDouble())); break; case Y1: r = AutoNumerical(y1(stack.PopDouble())); break; case SINC: r = AutoNumerical(sinc(stack.PopDouble())); break; case SIN: r = AutoNumerical(sin(stack.PopDouble())); break; case COS: r = AutoNumerical(cos(stack.PopDouble())); break; case TAN: r = AutoNumerical(tan(stack.PopDouble())); break; case ASIN: r = AutoNumerical(asin(stack.PopDouble())); break; case ACOS: r = AutoNumerical(acos(stack.PopDouble())); break; case ATAN: r = AutoNumerical(atan(stack.PopDouble())); break; case SINH: r = AutoNumerical(sinh(stack.PopDouble())); break; case COSH: r = AutoNumerical(cosh(stack.PopDouble())); break; case TANH: r = AutoNumerical(tanh(stack.PopDouble())); break; case ASINH: r = AutoNumerical(asinh(stack.PopDouble())); break; case ACOSH: r = AutoNumerical(acosh(stack.PopDouble())); break; case ATANH: r = AutoNumerical(atanh(stack.PopDouble())); break; case NOT: r = new Logical(!stack.PopBoolean()); break; case DIG: cout.precision(stack.PopInteger()); break; default: break; }; if (r != NULL) stack.Push(r);}//////void Calculator::ApplyBinary(Operation p){ double x, y; bool a, b; Item *r = NULL; string name; Item *value; switch(p.code) { case SWAP: stack.Swap(); break; case STO: name = stack.PopString(); value = stack.PopItem(); varlist.Store(value, name); break; case PLUS: y = stack.PopDouble(); x = stack.PopDouble(); r = AutoNumerical(x+y); break; case MINUS: y = stack.PopDouble(); x = stack.PopDouble(); r = AutoNumerical(x-y); break; case MULT: y = stack.PopDouble(); x = stack.PopDouble(); r = AutoNumerical(x*y); break; case DIV: y = stack.PopDouble(); x = stack.PopDouble(); r = AutoNumerical(x/y); break; case POW: y = stack.PopDouble(); x = stack.PopDouble(); r = AutoNumerical(pow(x, y)); break; case ROOT: y = stack.PopDouble(); x = stack.PopDouble(); r = AutoNumerical(pow(x, 1.0/y)); break; case HYPOT: y = stack.PopDouble(); x = stack.PopDouble(); r = AutoNumerical(hypot(x, y)); break; case JN: y = stack.PopInteger(); x = stack.PopDouble(); r = AutoNumerical(jn(int(y), x)); break; case YN: y = stack.PopInteger(); x = stack.PopDouble(); r = AutoNumerical(yn(int(y), x)); break; case LT: y = stack.PopDouble(); x = stack.PopDouble(); r = new Logical(x < y); break; case GT: y = stack.PopDouble(); x = stack.PopDouble(); r = new Logical(x > y); break; case LE: y = stack.PopDouble(); x = stack.PopDouble(); r = new Logical(x <= y); break; case GE: y = stack.PopDouble(); x = stack.PopDouble(); r = new Logical(x >= y); break; case EQ: y = stack.PopDouble(); x = stack.PopDouble(); r = new Logical(x == y); break; case NE: y = stack.PopDouble(); x = stack.PopDouble(); r = new Logical(x != y); break; case AND: a = stack.PopBoolean(); b = stack.PopBoolean(); r = new Logical(a && b); break; case OR: a = stack.PopBoolean(); b = stack.PopBoolean(); r = new Logical(a || b); break; case XOR: a = stack.PopBoolean(); b = stack.PopBoolean(); r = new Logical(a ^ b); break; default: break; }; if (r != NULL) stack.Push(r);}//////void Calculator::Enter(Item *p){ if (p != NULL) stack.Push(p);}//////void Calculator::Execute(Operation p){ if (p.arity == 0) ApplyZeroArity(p); if (p.arity == 1) ApplyUnary(p); if (p.arity == 2) ApplyBinary(p);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -