public CalcElement Calc(CalcElement element) { if (element.Value() < 0) { throw new ArgumentException(); } return(new NumericElement(Factorial((int)element.Value()))); }
//数式を解析して要素リストに変換します 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()
public CalcElement Calc(CalcElement element1, CalcElement element2) { checked { return(new NumericElement(element1.Value() * Math.Pow(10, element2.Value()))); } }
public CalcElement Calc(CalcElement element) { return(new NumericElement(Math.Cos(element.Value()) * this.Sign)); }
public CalcElement Calc(CalcElement element) { element.Sign = element.Sign * this.Sign; return(element); }
//括弧がない式を計算します 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()