1 /* 2 SPDX-FileCopyrightText: 2001-2013 Evan Teran <evan.teran@gmail.com> 3 SPDX-FileCopyrightText: 1996-2000 Bernd Johannes Wuebben <wuebben@kde.org> 4 5 SPDX-License-Identifier: GPL-2.0-or-later 6 */ 7 8 #pragma once 9 10 #include "knumber.h" 11 #include "stats.h" 12 #include <QStack> 13 14 class CalcEngine 15 { 16 public: 17 // operations that can be stored in calculation stack 18 enum Operation { 19 FUNC_EQUAL, 20 FUNC_PERCENT, 21 FUNC_BRACKET, 22 FUNC_OR, 23 FUNC_XOR, 24 FUNC_AND, 25 FUNC_LSH, 26 FUNC_RSH, 27 FUNC_ADD, 28 FUNC_SUBTRACT, 29 FUNC_MULTIPLY, 30 FUNC_DIVIDE, 31 FUNC_MOD, 32 FUNC_INTDIV, 33 FUNC_BINOM, 34 FUNC_POWER, 35 FUNC_PWR_ROOT 36 }; 37 38 enum Repeat { REPEAT_ALLOW, REPEAT_PREVENT }; 39 40 CalcEngine(); 41 42 KNumber lastOutput(bool &error) const; 43 44 void enterOperation(const KNumber &num, Operation func, Repeat allow_repeat = REPEAT_ALLOW); 45 46 void ArcCosDeg(const KNumber &input); 47 void ArcCosRad(const KNumber &input); 48 void ArcCosGrad(const KNumber &input); 49 void ArcSinDeg(const KNumber &input); 50 void ArcSinRad(const KNumber &input); 51 void ArcSinGrad(const KNumber &input); 52 void ArcTangensDeg(const KNumber &input); 53 void ArcTangensRad(const KNumber &input); 54 void ArcTangensGrad(const KNumber &input); 55 void AreaCosHyp(const KNumber &input); 56 void AreaSinHyp(const KNumber &input); 57 void AreaTangensHyp(const KNumber &input); 58 void Complement(const KNumber &input); 59 void CosDeg(const KNumber &input); 60 void CosRad(const KNumber &input); 61 void CosGrad(const KNumber &input); 62 void CosHyp(const KNumber &input); 63 void Cube(const KNumber &input); 64 void CubeRoot(const KNumber &input); 65 void Exp(const KNumber &input); 66 void Exp10(const KNumber &input); 67 void Factorial(const KNumber &input); 68 void Gamma(const KNumber &input); 69 void InvertSign(const KNumber &input); 70 void Ln(const KNumber &input); 71 void Log10(const KNumber &input); 72 void ParenClose(KNumber input); 73 void ParenOpen(const KNumber &input); 74 void Reciprocal(const KNumber &input); 75 void SinDeg(const KNumber &input); 76 void SinGrad(const KNumber &input); 77 void SinRad(const KNumber &input); 78 void SinHyp(const KNumber &input); 79 void Square(const KNumber &input); 80 void SquareRoot(const KNumber &input); 81 void StatClearAll(const KNumber &input); 82 void StatCount(const KNumber &input); 83 void StatDataNew(const KNumber &input); 84 void StatDataDel(const KNumber &input); 85 void StatMean(const KNumber &input); 86 void StatMedian(const KNumber &input); 87 void StatStdDeviation(const KNumber &input); 88 void StatStdSample(const KNumber &input); 89 void StatSum(const KNumber &input); 90 void StatSumSquares(const KNumber &input); 91 void TangensDeg(const KNumber &input); 92 void TangensRad(const KNumber &input); 93 void TangensGrad(const KNumber &input); 94 void TangensHyp(const KNumber &input); 95 96 void Reset(); 97 void setOnlyUpdateOperation(bool update); 98 bool getOnlyUpdateOperation() const; 99 100 private: 101 KStats stats; 102 103 struct Node { 104 KNumber number; 105 Operation operation; 106 }; 107 108 // Stack holds all operations and numbers that have not yet been 109 // processed, e.g. user types "2+3*", the calculation can not be 110 // executed, because "*" has a higher precedence than "+", so we 111 // need to wait for the next number. 112 // 113 // In the stack this would be stored as ((2,+),(3,*),...) 114 // 115 // "enterOperation": If the introduced Operation has lower priority 116 // than the preceding operations in the stack, then we can start to 117 // evaluate the stack (with "evalStack"). Otherwise we append the new 118 // Operation and number to the stack. 119 // 120 // E.g. "2*3+" evaluates to "6+", but "2+3*" can not be evaluated 121 // yet. 122 // 123 // We also take care of brackets, by writing a marker "FUNC_BRACKET" 124 // into the stack, each time the user opens one. When a bracket is 125 // closed, everything in the stack is evaluated until the first 126 // marker "FUNC_BRACKET" found. 127 QStack<Node> stack_; 128 129 KNumber last_number_; 130 131 Operation last_operation_; 132 KNumber last_repeat_number_; 133 bool only_update_operation_; 134 135 bool percent_mode_; 136 bool repeat_mode_; 137 138 bool evalStack(); 139 140 KNumber evalOperation(const KNumber &arg1, Operation operation, const KNumber &arg2); 141 }; 142 143