Beispiel #1
0
 // verejne metody
 /// <summary>
 /// Konstruktor objektu
 /// </summary>
 /// <description>
 /// Inicializace objektu
 /// </description>
 /// <param name="expr">
 ///   matematický výraz, který je nastaven do vlastnosti <see cref="Expression" />,
 ///   a jeho vyhodnocení je v <see cref="Value" />
 /// </param>
 public Calculation(string expr)
 {
     d_value     = double.NaN;
     t_calcError = CalcErrorType.None;
     o_mathLib   = new CalcMath();
     Expression  = expr;
 }
Beispiel #2
0
        /// <summary>
        /// Calculation error event handler
        /// </summary>
        /// <param name="errorType">Type of error</param>
        /// <param name="errorCode">Unique error identifier code</param>
        /// <param name="context">Error context</param>
        /// <param name="message">Error message</param>
        /// <param name="expression">Expression which caused the error, limited to the first 1024 characters</param>
        /// <param name="options">Error options</param>
        /// <param name="status">Return status</param>
        private void CalculatingError(CalcErrorType errorType, uint errorCode, string context, string message, string expression, uint options, ref CalcStatus status)
        {
            MessageBoxButton button = (errorType == CalcErrorType.ErrorExpression) ? MessageBoxButton.OKCancel : MessageBoxButton.OK;
            MessageBoxResult result = MessageBoxResult.OK;

            //Dispatch UI commands to the UI thread
            Dispatcher.Invoke(() =>
            {
                result = MessageBox.Show(
                    this,
                    $"An error has occurred whilst calculating\n\ncontext: {context}\nExpression: {expression}\n\n{message}\n",
                    "Calculation Error",
                    button,
                    MessageBoxImage.Error);
            });

            if (errorType == CalcErrorType.ErrorExpression && result != MessageBoxResult.OK)
            {
                status = CalcStatus.Aborted; //status = CalcStatus.Interrupted; //Interrupt to show the error in the output and keep the current variables
            }
        }
Beispiel #3
0
        private double EvaluateExpr(string expr)
        {
            t_calcError = CalcErrorType.None;
            Char[] workStr = PreprocessExpr(expr).ToArray(); // zavorkujeme aby se spravne zpetne vyhodnotil cely vyraz

            // zasobniky
            Stack <double> operandStack  = new Stack <double>();
            Stack <char>   operatorStack = new Stack <char>();

            // zpracovavame vyraz po znacich
            for (int i = 0; i < workStr.Length; i++)
            {
                // Zpracovani operandu
                if (Char.IsDigit(workStr[i])) // pokud je cislice
                {
                    double valtmp = double.NaN;
                    t_calcError = ProcessOperand(workStr, ref i, out valtmp);
                    if (t_calcError == CalcErrorType.None)
                    {
                        operandStack.Push(valtmp);
                    }
                    else
                    {
                        return(valtmp);
                    }

                    continue; // operand je zpracovan a index posunut na jeho konec ... opakujeme cyklus.
                }

                // Zpracovani operatoru
                if ("!L^@%*/-+".Contains(workStr[i]))
                {
                    // zkontrolujeme, jestli se jedna o platny unarni operator ... pokud nebude vyhodnocen jako unarni, tak metoda vraci true
                    if (!ProcessOperator(ref workStr, i))
                    {
                        t_calcError = CalcErrorType.ExprFormatError;
                        return(double.NaN);
                    }
                    // pokud je operator mensi priority nez posledni operator na zasobniku, provedem predchozi operaci
                    while (
                        operatorStack.Count > 0 &&
                        GetOperatorPriority(operatorStack.Peek()) >= GetOperatorPriority(workStr[i])
                        )
                    {
                        // Pokusime se provest operaci na zasobnicich
                        t_calcError = PopOperation(operatorStack, operandStack);
                        if (t_calcError != CalcErrorType.None)
                        {
                            return(operandStack.Pop()); // vysledek (inf/NaN) je na vrcholu
                        }
                    }

                    // ulozime aktualni operator
                    operatorStack.Push(workStr[i]);
                    continue;
                }
                // zavorky oteviraci se ukladaji pro skonceni vyhodnoceni podvyrazu
                else if (workStr[i] == '(')
                {
                    operatorStack.Push(workStr[i]);
                }
                // uzaviraci zavorka znamena vyhodnot vsechno zpetne az do oteviraci zavorky
                else if (workStr[i] == ')')
                {
                    if (operatorStack.Count < 1)
                    {
                        t_calcError = CalcErrorType.ExprFormatError;
                        return(double.NaN);
                    }
                    while (operatorStack.Peek() != '(')
                    {
                        // Pokusime se provest operaci na zasobnicich
                        t_calcError = PopOperation(operatorStack, operandStack);
                        if (t_calcError != CalcErrorType.None)
                        {
                            return(operandStack.Pop()); // vysledek (inf/NaN) je na vrcholu
                        }
                    }
                    operatorStack.Pop();
                }
                else // neznamy znak
                {
                    t_calcError = CalcErrorType.ExprFormatError;
                    return(double.NaN);
                }
            }
            // na zasobniku by mela zustat jenom jedna hodnota
            if (operandStack.Count != 1)
            {
                t_calcError = CalcErrorType.ExprFormatError;
                return(double.NaN);
            }
            return(operandStack.Pop());//double.NaN;
        }