File indexing completed on 2024-04-28 09:45:26
0001 /* 0002 SPDX-FileCopyrightText: 2001-2013 Evan Teran <evan.teran@gmail.com> 0003 SPDX-FileCopyrightText: 1996-2000 Bernd Johannes Wuebben <wuebben@kde.org> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 0008 #pragma once 0009 0010 #include "knumber.h" 0011 #include "stats.h" 0012 #include <QStack> 0013 0014 class CalcEngine 0015 { 0016 public: 0017 // operations that can be stored in calculation stack 0018 enum Operation { 0019 FUNC_EQUAL, 0020 FUNC_PERCENT, 0021 FUNC_BRACKET, 0022 FUNC_OR, 0023 FUNC_XOR, 0024 FUNC_AND, 0025 FUNC_LSH, 0026 FUNC_RSH, 0027 FUNC_ADD, 0028 FUNC_SUBTRACT, 0029 FUNC_MULTIPLY, 0030 FUNC_DIVIDE, 0031 FUNC_MOD, 0032 FUNC_INTDIV, 0033 FUNC_BINOM, 0034 FUNC_POWER, 0035 FUNC_PWR_ROOT 0036 }; 0037 0038 enum Repeat { REPEAT_ALLOW, REPEAT_PREVENT }; 0039 0040 CalcEngine(); 0041 0042 KNumber lastOutput(bool &error) const; 0043 0044 void enterOperation(const KNumber &num, Operation func, Repeat allow_repeat = REPEAT_ALLOW); 0045 0046 void ArcCosDeg(const KNumber &input); 0047 void ArcCosRad(const KNumber &input); 0048 void ArcCosGrad(const KNumber &input); 0049 void ArcSinDeg(const KNumber &input); 0050 void ArcSinRad(const KNumber &input); 0051 void ArcSinGrad(const KNumber &input); 0052 void ArcTangensDeg(const KNumber &input); 0053 void ArcTangensRad(const KNumber &input); 0054 void ArcTangensGrad(const KNumber &input); 0055 void AreaCosHyp(const KNumber &input); 0056 void AreaSinHyp(const KNumber &input); 0057 void AreaTangensHyp(const KNumber &input); 0058 void Complement(const KNumber &input); 0059 void CosDeg(const KNumber &input); 0060 void CosRad(const KNumber &input); 0061 void CosGrad(const KNumber &input); 0062 void CosHyp(const KNumber &input); 0063 void Cube(const KNumber &input); 0064 void CubeRoot(const KNumber &input); 0065 void Exp(const KNumber &input); 0066 void Exp10(const KNumber &input); 0067 void Factorial(const KNumber &input); 0068 void Gamma(const KNumber &input); 0069 void InvertSign(const KNumber &input); 0070 void Ln(const KNumber &input); 0071 void Log10(const KNumber &input); 0072 void ParenClose(KNumber input); 0073 void ParenOpen(const KNumber &input); 0074 void Reciprocal(const KNumber &input); 0075 void SinDeg(const KNumber &input); 0076 void SinGrad(const KNumber &input); 0077 void SinRad(const KNumber &input); 0078 void SinHyp(const KNumber &input); 0079 void Square(const KNumber &input); 0080 void SquareRoot(const KNumber &input); 0081 void StatClearAll(const KNumber &input); 0082 void StatCount(const KNumber &input); 0083 void StatDataNew(const KNumber &input); 0084 void StatDataDel(const KNumber &input); 0085 void StatMean(const KNumber &input); 0086 void StatMedian(const KNumber &input); 0087 void StatStdDeviation(const KNumber &input); 0088 void StatStdSample(const KNumber &input); 0089 void StatSum(const KNumber &input); 0090 void StatSumSquares(const KNumber &input); 0091 void TangensDeg(const KNumber &input); 0092 void TangensRad(const KNumber &input); 0093 void TangensGrad(const KNumber &input); 0094 void TangensHyp(const KNumber &input); 0095 0096 void Reset(); 0097 void setOnlyUpdateOperation(bool update); 0098 bool getOnlyUpdateOperation() const; 0099 0100 private: 0101 KStats stats; 0102 0103 struct Node { 0104 KNumber number; 0105 Operation operation; 0106 }; 0107 0108 // Stack holds all operations and numbers that have not yet been 0109 // processed, e.g. user types "2+3*", the calculation can not be 0110 // executed, because "*" has a higher precedence than "+", so we 0111 // need to wait for the next number. 0112 // 0113 // In the stack this would be stored as ((2,+),(3,*),...) 0114 // 0115 // "enterOperation": If the introduced Operation has lower priority 0116 // than the preceding operations in the stack, then we can start to 0117 // evaluate the stack (with "evalStack"). Otherwise we append the new 0118 // Operation and number to the stack. 0119 // 0120 // E.g. "2*3+" evaluates to "6+", but "2+3*" can not be evaluated 0121 // yet. 0122 // 0123 // We also take care of brackets, by writing a marker "FUNC_BRACKET" 0124 // into the stack, each time the user opens one. When a bracket is 0125 // closed, everything in the stack is evaluated until the first 0126 // marker "FUNC_BRACKET" found. 0127 QStack<Node> stack_; 0128 0129 KNumber last_number_; 0130 0131 Operation last_operation_; 0132 KNumber last_repeat_number_; 0133 bool only_update_operation_; 0134 0135 bool percent_mode_; 0136 bool repeat_mode_; 0137 0138 bool evalStack(); 0139 0140 KNumber evalOperation(const KNumber &arg1, Operation operation, const KNumber &arg2); 0141 }; 0142