Ejemplo n.º 1
0
 public CalcElement Calc(CalcElement element)
 {
     if (element.Value() < 0)
     {
         throw new ArgumentException();
     }
     return(new NumericElement(Factorial((int)element.Value())));
 }
Ejemplo n.º 2
0
        //数式を解析して要素リストに変換します
        private static IList <CalcElement> GetElementList(string formula)
        {
            var         elementList = new List <CalcElement>();
            CalcElement element     = null;

            //式から1文字ずつ取得してループします
            foreach (var c in formula)
            {
                if (('9' >= c && c >= '0') || c == '.')
                {
                    //数値の場合

                    //現在の要素が演算子の場合は、現在の要素をリストに追加して、次の要素の準備をします
                    if (element != null && element is IOperator)
                    {
                        elementList.Add(element);
                        element = null;
                    }

                    //要素に文字を追加します
                    if (element == null)
                    {
                        element = new NumericElement();
                    }
                    ((NumericElement)element).ElementString += c;
                }
                else
                {
                    //演算子の場合

                    //現在の要素がある場合は、現在の要素をリストに追加します
                    if (element != null)
                    {
                        elementList.Add(element);
                    }

                    element = null; //次の要素
                    if (c == '*')
                    {
                        element = new MulElement         {
                            Priority = 2
                        }
                    }
                    ;
                    if (c == '/')
                    {
                        element = new DivElement         {
                            Priority = 2
                        }
                    }
                    ;
                    if (c == '^')
                    {
                        element = new PowElement         {
                            Priority = 3
                        }
                    }
                    ;
                    if (c == '!')
                    {
                        element = new FactorialElement   {
                            Priority = 4
                        }
                    }
                    ;
                    if (c == '√')
                    {
                        element = new SqrtElement        {
                            Priority = 5
                        }
                    }
                    ;
                    if (c == 'S')
                    {
                        element = new SinElement         {
                            Priority = 5
                        }
                    }
                    ;
                    if (c == 'C')
                    {
                        element = new CosElement         {
                            Priority = 5
                        }
                    }
                    ;
                    if (c == 'E')
                    {
                        element = new ExponentialElement {
                            Priority = 6
                        }
                    }
                    ;
                    if (c == '+')
                    {
                        element = new AddElement         {
                            Priority = 7
                        }
                    }
                    ;
                    if (c == '-')
                    {
                        element = new SubElement         {
                            Priority = 7
                        }
                    }
                    ;
                    element.ElementString = c.ToString();
                }
            }

            //現在の要素をリストに追加する
            elementList.Add(element);

            return(elementList);
        } //GetElementList()
Ejemplo n.º 3
0
 public CalcElement Calc(CalcElement element1, CalcElement element2)
 {
     checked {
         return(new NumericElement(element1.Value() * Math.Pow(10, element2.Value())));
     }
 }
Ejemplo n.º 4
0
 public CalcElement Calc(CalcElement element)
 {
     return(new NumericElement(Math.Cos(element.Value()) * this.Sign));
 }
Ejemplo n.º 5
0
 public CalcElement Calc(CalcElement element)
 {
     element.Sign = element.Sign * this.Sign;
     return(element);
 }
Ejemplo n.º 6
0
        //括弧がない式を計算します
        private static double CalcSub(string formula)
        {
            #region //ログ出力 式
            #if DEBUG
            Console.WriteLine("----------------------------------------");
            Console.WriteLine("式 = " + formula);
            #endif
            #endregion

            //置換処理
            formula = formula.Replace(" ", "");                 //スペースを全て削除
            formula = formula.Replace("\r", "");                //改行を全て削除
            formula = formula.Replace("\n", "");                //改行を全て削除
            formula = formula.Replace("\t", "");                //タブを全て削除
            formula = formula.Replace("π", Math.PI.ToString()); //πを Math.PI に置換します

            // = がある場合は、左辺のみを有効にする
            int eqIndex = formula.IndexOf("=");
            if (eqIndex >= 0)
            {
                formula = formula.Substring(0, eqIndex);
            }

            //大文字で統一します
            formula = formula.ToUpper();

            //関数を1文字の記号に置換します(演算子と同様に1文字にした方が解析が簡単なため)
            formula = formula.Replace("SIN", "S");
            formula = formula.Replace("COS", "C");

            #region //ログ出力 式 -> 要素リスト
            #if DEBUG
            Console.WriteLine("式 -> 要素リスト");
            #endif
            #endregion

            //数式を解析して要素リストに変換します
            var elementList = GetElementList(formula);

            #region //ログ出力 : 要素リスト
            #if DEBUG
            for (int i = 0; i < elementList.Count(); i++)
            {
                Console.WriteLine("[{0}] = {1}", i, elementList[i].ElementString);
            }
            Console.WriteLine("----------------------------------------");
            #endif
            #endregion

            int index = -1;

            //最優先の演算子を取得して、演算子がなくなるまでループします
            while ((index = GetTopPriorityElementIndex(elementList)) >= 0)
            {
                //各要素を取得します
                var valueElement1   = GetElement(elementList, index - 1);
                var operatorElement = GetElement(elementList, index);
                var valueElement2   = GetElement(elementList, index + 1);

                //計算します
                CalcElement resultElement = null;
                if (operatorElement is IOperatorElement)
                {
                    resultElement = ((IOperatorElement     )operatorElement).Calc(valueElement1, valueElement2);
                }
                if (operatorElement is IOperatorLeftElement)
                {
                    resultElement = ((IOperatorLeftElement )operatorElement).Calc(valueElement1);
                }
                if (operatorElement is IOperatorRightElement)
                {
                    resultElement = ((IOperatorRightElement)operatorElement).Calc(valueElement2);
                }

                //計算結果をリストに反映します
                elementList[index] = resultElement;

                //リストから要素を削除します
                if (operatorElement is IOperatorElement || operatorElement is IOperatorRightElement)
                {
                    elementList.RemoveAt(index + 1);
                }
                if (operatorElement is IOperatorElement || operatorElement is IOperatorLeftElement)
                {
                    elementList.RemoveAt(index - 1);
                }
            }

            //余った数値の要素を全て加算します
            var result = elementList.Sum(_ => _.Value());

            #region //ログ出力
            #if DEBUG
            Console.WriteLine("□小計 {0} = {1}", formula, result);
            #endif
            #endregion

            return(result);
        } //CalcSub()