[C#]計算以字串表示的數學運算式結果

  • 21427
  • 0

[C#]計算以字串表示的數學運算式結果

 

2010/12/03 小朱推薦的 NCalc 很不錯,參考 NCalc: 處理數學運算的好幫手 

 

一、問題描述

當有個數學運算式以 string 變數表示,例如


	string str = "91 + 91 * 100";

如何計算此數學運算式的結果

 

二、方法

可以實現的方式相當多,在此文提供兩種方法

方法 1 : 使用 ScriptControl 調用 VBScript 進行計算

首先將 Microosft Script Control 1.0 加入參考,在專案的參考上按滑鼠右鍵,選擇 [加入參考],切換到 [COM] 索引標籤,找出 Microosft Script Control 1.0 按 [確定]。

SNAGHTML3b518c

範例程式碼


	/// <summary>
        /// 使用 ScriptControl 與 VBScript
        /// </summary>
        /// <param name="sExpression">數值運算式</param>
        /// <returns>數值運算結果</returns>
        public static double EvaluateUsingScriptControl(string sExpression)
        {
            MSScriptControl.ScriptControl sc = new MSScriptControl.ScriptControl();
            sc.Language = "VBScript";
            return double.Parse(sc.Eval(sExpression).ToString());
        }

 

方法 2 : 使用 XPathNavigator.Evaluate 進行計算

XPathNavigator.Evaluate 方法 (XPathExpression) : 評估 XPathExpression,並傳回具型別的結果。

命名空間: System.Xml.XPath
組件: System.Xml (在 system.xml.dll 中)

參數
expr
可以接受評估的 XPathExpression。

傳回值
運算式的結果 (布林值、數字、字串或節點集)。這會分別對應至 Boolean、Double、String 或 XPathNodeIterator 等物件。

 

要使用 XPathNavigator.Evaluate,必須先將運算式修改為 XPathExpression,此部分透過 regex 處理

 

範例程式碼


	/// <summary>
        /// 使用 XPathDocument
        /// </summary>
        /// <param name="sExpression">數值運算式</param>
        /// <returns>數值運算結果</returns>
        public static double EvaluateUsingXPathDocument(string sExpression)
        {
            var xsltExpression = string.Format("number({0})",
                    new Regex(@"([\+\-\*])").Replace(sExpression, " ${1} ")
                                            .Replace("/", " div ")
                                            .Replace("%", " mod "));

            return (double)new XPathDocument(new StringReader("<r/>")).CreateNavigator().Evaluate(xsltExpression);
        }

 

三、示範

程式碼下載 WinFormsEval.zip


	using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Xml.XPath;
using System.IO;
using System.Text.RegularExpressions;

namespace WinFormsEval
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnEvaluate_Click(object sender, EventArgs e)
        {
            string sExpression = this.txtExpression.Text.Trim();
            if (sExpression.Length == 0) return;

            MessageBox.Show(EvaluateUsingScriptControl(sExpression).ToString(), "Evaluate Using ScriptControl");
            MessageBox.Show(EvaluateUsingXPathDocument(sExpression).ToString(), "Evaluate Using XPathDocument");

            this.txtExpression.Clear();
        }

        /// <summary>
        /// 使用 ScriptControl 與 VBScript
        /// </summary>
        /// <param name="sExpression">數值運算式</param>
        /// <returns>數值運算結果</returns>
        public static double EvaluateUsingScriptControl(string sExpression)
        {
            MSScriptControl.ScriptControl sc = new MSScriptControl.ScriptControl();
            sc.Language = "VBScript";
            return double.Parse(sc.Eval(sExpression).ToString());
        }
        
        /// <summary>
        /// 使用 XPathDocument
        /// </summary>
        /// <param name="sExpression">數值運算式</param>
        /// <returns>數值運算結果</returns>
        public static double EvaluateUsingXPathDocument(string sExpression)
        {
            var xsltExpression = string.Format("number({0})",
                    new Regex(@"([\+\-\*])").Replace(sExpression, " ${1} ")
                                            .Replace("/", " div ")
                                            .Replace("%", " mod "));

            return (double)new XPathDocument(new StringReader("<r/>")).CreateNavigator().Evaluate(xsltExpression);
        }
    }
}

 

 

四、相關參考與連結

MSDN 論壇 - 如何在vb中求出由若干变量组成的算数表达式的结果?

Is it possible to translate a user-entered mathematical equation into C# code at runtime?

Is there a string math evaluator in .NET?