示例#1
0
        public static double Solve(Function function, double x)
        {
            Stack P = new Stack();
            double s = 0;
            double a, b;
            for (int i = 0; i < function.RPNsequence.Length; i++)
            {
                if (string.IsNullOrEmpty(function.RPNsequence[i])) continue;

                else
                {
                    if (char.IsDigit(function.RPNsequence[i][0]))
                    {
                        P.Push(function.RPNsequence[i]);
                    }
                    else if ((char.IsLetter(function.RPNsequence[i][0])) &&
                        (function.RPNsequence[i][0] != function.Argument) && (function.RPNsequence[i][0] != '\u03c0') &&
                        (function.RPNsequence[i][0] != 'e'))
                    {
                        double X = Convert.ToDouble(P.Pop());
                        switch (function.RPNsequence[i])
                        {
                            case "sqrt":
                                P.Push(Math.Sqrt(X));
                                break;
                            case "abs":
                                P.Push(Math.Abs(X));
                                break;
                            case "sin":
                                P.Push(Math.Sin(X));
                                break;
                            case "sinh":
                                P.Push(Math.Sinh(X));
                                break;
                            case "cosh":
                                P.Push(Math.Cosh(X));
                                break;
                            case "cos":
                                P.Push(Math.Cos(X));
                                break;
                            case "cth":
                                P.Push(1 / Math.Tanh(X));
                                break;
                            case "tanh":
                                P.Push(Math.Tanh(X));
                                break;
                            case "tan":
                                P.Push(Math.Tan(X));
                                break;
                            case "cot":
                                P.Push(1 / Math.Tan(X));
                                break;
                            case "аbs":
                                P.Push(Math.Abs(X));
                                break;
                            case "ln":
                                P.Push(Math.Log(X));
                                break;
                            case "arsinh":
                                P.Push(Math.Log(X + Math.Sqrt(X * X + 1)));
                                break;
                            case "arcsin":
                                P.Push(Math.Asin(X));
                                break;
                            case "arcosh":
                                P.Push(Math.Log(X + Math.Sqrt(X + 1) * Math.Sqrt(X - 1)));
                                break;
                            case "arccos":
                                P.Push(Math.Acos(X));
                                break;
                            case "artanh":
                                P.Push(Math.Log((X + 1) / (X - 1)) / 2);
                                break;
                            case "arccot":
                                P.Push(Math.Atan(-1 * X) + Math.PI / 2);
                                break;
                            case "arcth":
                                P.Push(Math.Log((X + 1) / (1 - X)) / 2);
                                break;
                            case "arctan":
                                P.Push(Math.Atan(X));
                                break;
                            case "log":
                                P.Push(Math.Log(Convert.ToDouble(P.Pop()), X));
                                break;
                            case "sign":
                                P.Push(Math.Sign(X));
                                break;
                            case "rem":
                                P.Push(Convert.ToDouble(P.Pop()) % X);
                                break;
                            case "sec":
                                P.Push(1 / Math.Cos(x));
                                break;
                            case "csc":
                                P.Push(1 / Math.Sin(x));
                                break;
                            case "arcsec":
                                P.Push(Math.Acos(1 / X));
                                break;
                            case "arccsc":
                                P.Push(Math.Asin(1 / X));
                                break;
                            case "sech":
                                P.Push(1 / Math.Cosh(x));
                                break;
                            case "csch":
                                P.Push(1 / Math.Sinh(x));
                                break;
                            case "arsech":
                                P.Push(Math.Log(1 / x + Math.Sqrt(1 / x + 1) * Math.Sqrt(1 / x - 1)));
                                break;
                            case "arcsch":
                                P.Push(Math.Log(1 / x + Math.Sqrt(1 / x * x + 1)));
                                break;

                        }
                    }
                    else
                    {
                        if (function.RPNsequence[i][0] == 'e') P.Push(Math.E);
                        else if (function.RPNsequence[i][0] == '\u03c0') P.Push(Math.PI);
                        else if (function.RPNsequence[i][0] == function.Argument) P.Push(x);
                        else
                        {
                            b = Convert.ToDouble(P.Pop());
                            a = Convert.ToDouble(P.Pop());
                            switch (function.RPNsequence[i][0])
                            {
                                ///binary operations
                                case '+':
                                    P.Push(a + b);
                                    break;
                                case '-':
                                    P.Push(a - b);
                                    break;
                                case '*':
                                    P.Push(a * b);
                                    break;
                                case '/':
                                    P.Push(a / b);
                                    s = b;
                                    break;
                                case '^':
                                    if (b > 1)
                                    {
                                        if ((a < 0) || (a > 0))
                                        {
                                            P.Push(Math.Pow(a, b));
                                        }
                                        else
                                        {
                                            P.Push(0);
                                        }
                                    }
                                    else if ((b < 1) && (b > 0))
                                    {
                                        if (a > 0)
                                        {
                                            P.Push(Math.Pow(a, b));
                                        }
                                        else if (a < 0)
                                        {
                                            if (s % 2 == 1)
                                            {
                                                P.Push(-Math.Pow(Math.Abs(a), b));
                                            }
                                            else P.Push(Math.Pow(a, b));
                                        }
                                        else
                                        {
                                            P.Push(0);
                                        }
                                    }
                                    else if (b == 1)
                                    {
                                        P.Push(a);
                                    }
                                    else if (b == 0)
                                    {
                                        if (a == 0)
                                        {
                                            P.Push(0);
                                        }
                                        else P.Push(1);
                                    }
                                    break;
                                case ';':
                                    P.Push(b);
                                    P.Push(a);
                                    break;
                                ///unary operations
                                case '~':
                                    P.Push(a);
                                    P.Push(-1 * Convert.ToDouble(b));
                                    break;
                                default:
                                    goto y;
                            }//end switch
                        }//end else
                    }
                }
            }
            y: return Convert.ToDouble(P.Pop());
        }
示例#2
0
        private void ConvertToRPN()
        {
            if (name[0] == '-')
            {
                name.Remove(0, 1);
                name.Insert(0, '~');
            }
            name.Replace("(-", "(~");


            Stack S = new Stack();
            RPNsequence = new string[name.Length];

            int j = 0;

            ///Перевод выражения в польскую запись
            string function = string.Empty;


            int e = 0;
            for (; j < name.Length; j++)
            {
                if ((char.IsDigit(name[j])) || (name[j] == '\u03c0')
                    || (name[j] == 'e') || (name[j] == Argument))//в буфере число?
                {
                    RPNsequence[e] += name[j];
                    if ((j != name.Length - 1) && (!char.IsDigit(name[j + 1]))) e++;
                }
                else if ((char.IsLetter(name[j])) && (name[j] != Argument) && (name[j] != '\u03c0') && (name[j] != 'e'))
                {
                    while (char.IsLetter(name[j]))
                    {
                        function += name[j];
                        j++;
                    }
                    j--;
                    S.Push(function);
                    function = string.Empty;
                }
                else if (name[j] == ';')
                {
                    continue;
                }
                else
                {
                    if (S.IsEmpty() == true)
                    {
                        S.Push(name[j]);
                    }
                    else if (GetPriority(Convert.ToString(S.CopyElement())) < GetPriority(name[j].ToString())) //сравнение приоритетов операций
                    {
                        S.Push(name[j]);
                    }
                    ///
                    else if (name[j] == '(')
                    {
                        S.Push(name[j]);
                    }
                    else if (name[j] == ')')
                    {
                        while (GetPriority(Convert.ToString(S.CopyElement())) != 1)
                        {
                            RPNsequence[e] += S.Pop().ToString();
                            e++;
                        }
                        S.DeleteElement();
                    }
                    else
                    {
                        while (GetPriority(Convert.ToString(S.CopyElement())) >= GetPriority(name[j].ToString()))
                        {
                            RPNsequence[e] += S.Pop().ToString();
                            e++;
                        }
                        S.Push(name[j]);
                    }


                }

            }

            while (S.IsEmpty() != true)
            {
                e++;
                RPNsequence[e] += S.Pop().ToString();
            }

        }