C# と VB.NET の質問掲示板

わんくま同盟

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

ツリー一括表示

C#で関数を含む計算式文字列を処理して計算する /星は昴 (24/11/20(Wed) 12:07) #103439
Re[1]: C#で関数を含む計算式文字列を処理して計算する /kiku (24/11/20(Wed) 13:02) #103440
  └ Re[2]: C#で関数を含む計算式文字列を処理して計算する /星は昴 (24/11/20(Wed) 14:59) #103441 解決済み
    └ Re[3]: C#で関数を含む計算式文字列を処理して計算する /くま (24/11/20(Wed) 15:40) #103442
      ├ Re[4]: C#で関数を含む計算式文字列を処理して計算する /くま (24/11/20(Wed) 15:53) #103443 解決済み
      │└ Re[5]: C#で関数を含む計算式文字列を処理して計算する /星は昴 (24/11/20(Wed) 18:47) #103444 解決済み
      └ Re[4]: C#で関数を含む計算式文字列を処理して計算する /星は昴 (24/11/21(Thu) 15:17) #103445
        └ Re[5]: C#で関数を含む計算式文字列を処理して計算する /kiku (24/11/21(Thu) 15:39) #103446
          └ Re[6]: C#で関数を含む計算式文字列を処理して計算する /星は昴 (24/11/21(Thu) 15:55) #103447 解決済み


親記事 / ▼[ 103440 ]
■103439 / 親階層)  C#で関数を含む計算式文字列を処理して計算する
□投稿者/ 星は昴 (5回)-(2024/11/20(Wed) 12:07:32)

分類:[C#] 

 C# で関数を含む計算式文字列、たとえば

"(7+3)/2"
"21^2"
"sin(3.141592654/4)"
"abs(-2)"

などを簡単に計算できるクラスを作成したいのですが、ネットを検索してもその方法がなかなか見当たりません。
https://dobon.net/vb/dotnet/programing/eval.html
を見ましたが、リンク切れがあったり、解説が日本語ではないためよくわかりません。
 具体的には

private void BtnCalc_Click(object sender, EventArgs e)
{
  var S = label_A.Text; // S = "16^2/7" or "log(1.5)" …etc
  double x = 0;
  EasyCalc1 = new EasyCalc();
  EasyCalc1.SetExpression(S);      // 式文字列から木を作る
  double y = EGCalc1.GetValue(x, Err); // 木から値を計算する
  label_B.Text = y.ToString();
}

のように使える EasyCalc クラスのようなものを作りたいのです。
 四則演算だけなら System.Data.DataTable が手軽でいいのですが・・・
 昔、Pascal (Delphi) で、そういうクラスを作ったのですが、ポインタを使っているのでそのまま移植するのは少し躊躇します。

[ □ Tree ] 返信 編集キー/

▲[ 103439 ] / ▼[ 103441 ]
■103440 / 1階層)  Re[1]: C#で関数を含む計算式文字列を処理して計算する
□投稿者/ kiku (446回)-(2024/11/20(Wed) 13:02:47)
No103439 (星は昴 さん) に返信
>  C# で関数を含む計算式文字列、たとえば
> "(7+3)/2"
> "21^2"
> "sin(3.141592654/4)"
> "abs(-2)"
>
> などを簡単に計算できるクラスを作成したいのですが、ネットを検索してもその方法がなかなか見当たりません。

自身では使ったことがないのですが、
下記が利用できそうです。
検討してみてはどうでしょうか?
https://ufcpp.net/study/csharp/cheatsheet/apscripting/
[ 親 103439 / □ Tree ] 返信 編集キー/

▲[ 103440 ] / ▼[ 103442 ]
■103441 / 2階層)  Re[2]: C#で関数を含む計算式文字列を処理して計算する
□投稿者/ 星は昴 (6回)-(2024/11/20(Wed) 14:59:00)
No103440 (kiku さん) に返信
> ■No103439 (星は昴 さん) に返信
> 検討してみてはどうでしょうか?
> https://ufcpp.net/study/csharp/cheatsheet/apscripting/

 回答まことにありがとうございました。
解決済み
[ 親 103439 / □ Tree ] 返信 編集キー/

▲[ 103441 ] / ▼[ 103443 ] ▼[ 103445 ]
■103442 / 3階層)  Re[3]: C#で関数を含む計算式文字列を処理して計算する
□投稿者/ くま (32回)-(2024/11/20(Wed) 15:40:27)
2024/11/20(Wed) 16:03:36 編集(投稿者)
JScriptバージョン

//----- EasyCalcクラス(開始)
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;

public class EasyCalc
{
    private System.Type comType = null;
    private dynamic comInstance = null;
    /// <summary>
    /// コンストラクタ
    /// </summary>
    public EasyCalc()
    {
        this.comType = System.Type.GetTypeFromProgID("MSScriptControl.ScriptControl");
        this.comInstance = System.Activator.CreateInstance(this.comType);
        this.comInstance.Language = "JScript";
    }
    /// <summary>
    /// デストラクタ
    /// </summary>
    ~EasyCalc()
    {
        Marshal.ReleaseComObject(this.comInstance);
        this.comInstance = null;
        this.comType = null;
    }

    /// <summary>
    /// 計算式用プロパティ
    /// </summary>
    public string Expression { get; set; } = string.Empty;

    /// <summary>
    /// 計算を実行する。
    /// </summary>
    /// <param name="values">値一覧</param>
    /// <param name="err">エラーの場合、エラー内容。それ以外の場合は、string.Empty。</param>
    /// <returns>計算結果</returns>
    public double GetValue(string values, ref string err)
    {
        err = string.Empty;
        try
        {
            List<string> lstFormula = new List<string>();
            lstFormula.Add(values);
            lstFormula.Add(this.Expression);
            object result = this.comInstance.eval(string.Join(Environment.NewLine, lstFormula));
            return Convert.ToDouble(result);
        }
        catch (Exception e)
        {
            err = string.Format("{0}", e);
            return 0;
        }
    }
}
//----- EasyCalcクラス(終了)

//----- テスト(開始)
            EasyCalc EasyCalc1 = new EasyCalc();
            EasyCalc1.Expression = "a + b + 3 + 4";
            string values = "var a = 1; var b = 2;";
            string error = string.Empty;
            double result = EasyCalc1.GetValue(values, ref error);
            Console.WriteLine("result:{0} error:{1}", result, error);

            // 使える計算式は以下のURLを参照      
            // h t t p s ://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math
            EasyCalc1.Expression = "Math.log(1.5)";
            values = string.Empty;
            error = string.Empty;
            result = EasyCalc1.GetValue(values, ref error);
            Console.WriteLine("result:{0} error:{1}", result, error);
//----- テスト(終了)

[ 親 103439 / □ Tree ] 返信 編集キー/

▲[ 103442 ] / ▼[ 103444 ]
■103443 / 4階層)  Re[4]: C#で関数を含む計算式文字列を処理して計算する
□投稿者/ くま (33回)-(2024/11/20(Wed) 15:53:50)
エラーの場合
EasyCalc EasyCalc1 = new EasyCalc();
EasyCalc1.Expression = "c + 10";
string values = string.Empty;
string error = string.Empty;
double result = EasyCalc1.GetValue(values, ref error);
Console.WriteLine("result:{0} error:{1}", result, error);

タイミングがずれた...
完了済みにします。
解決済み
[ 親 103439 / □ Tree ] 返信 編集キー/

▲[ 103443 ] / 返信無し
■103444 / 5階層)  Re[5]: C#で関数を含む計算式文字列を処理して計算する
□投稿者/ 星は昴 (7回)-(2024/11/20(Wed) 18:47:08)
No103443 (くま さん) に返信
 丁寧な回答まことにありがとうございました。とても参考になります。

解決済み
[ 親 103439 / □ Tree ] 返信 編集キー/

▲[ 103442 ] / ▼[ 103446 ]
■103445 / 4階層)  Re[4]: C#で関数を含む計算式文字列を処理して計算する
□投稿者/ 星は昴 (8回)-(2024/11/21(Thu) 15:17:14)
No103442 (くま さん) に返信
> 2024/11/20(Wed) 16:03:36 編集(投稿者)
> 
> //----- テスト(開始)
>             EasyCalc EasyCalc1 = new EasyCalc();
>             EasyCalc1.Expression = "a + b + 3 + 4";
>             string values = "var a = 1; var b = 2;";
>             string error = string.Empty;
>             double result = EasyCalc1.GetValue(values, ref error);
>             Console.WriteLine("result:{0} error:{1}", result, error);
> 
>             // 使える計算式は以下のURLを参照      
>             // h t t p s ://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Math
>             EasyCalc1.Expression = "Math.log(1.5)";
>             values = string.Empty;
>             error = string.Empty;
>             result = EasyCalc1.GetValue(values, ref error);
>             Console.WriteLine("result:{0} error:{1}", result, error);
> //----- テスト(終了)

 ちょっと時間が取れなくて、教えてもらったコードを今確認しましたが、両方ともエラーが出ます。

private void btnCalc_Click(object sender, EventArgs e)
{
    EasyCalc EasyCalc1 = new EasyCalc();
    EasyCalc1.Expression = "a + b + 3 + 4";
    string values = "var a = 1; var b = 2;";
    string error = string.Empty;
    double result = EasyCalc1.GetValue(values, ref error);
    TbxOut.Text = String.Format("result:{0} error:{1}", result, error); //Console→TextBox
}
result:10 error:

private void btnCalc_Click(object sender, EventArgs e)
{
    EasyCalc EasyCalc1 = new EasyCalc();
    EasyCalc1.Expression = "Math.log(1.5)";
    string values = string.Empty;
    string error = string.Empty;
    double result = EasyCalc1.GetValue(values, ref error);
    TbxOut.Text = String.Format("result:{0} error:{1}", result, error);
}
result:0.405465108108164 error:

[ 親 103439 / □ Tree ] 返信 編集キー/

▲[ 103445 ] / ▼[ 103447 ]
■103446 / 5階層)  Re[5]: C#で関数を含む計算式文字列を処理して計算する
□投稿者/ kiku (447回)-(2024/11/21(Thu) 15:39:27)
No103445 (星は昴 さん) に返信
> ■No103442 (くま さん) に返信
>>2024/11/20(Wed) 16:03:36 編集(投稿者)
>  ちょっと時間が取れなくて、教えてもらったコードを今確認しましたが、両方ともエラーが出ます。
>
> result:10 error:
> result:0.405465108108164 error:

動作確認していない状態でコメントします。
上記の「error:」の後ろに何も表示されていないという
ことは、エラーが出ていないということではないかと思いました。

[ 親 103439 / □ Tree ] 返信 編集キー/

▲[ 103446 ] / 返信無し
■103447 / 6階層)  Re[6]: C#で関数を含む計算式文字列を処理して計算する
□投稿者/ 星は昴 (9回)-(2024/11/21(Thu) 15:55:28)
No103446 (kiku さん) に返信
> ■No103445 (星は昴 さん) に返信
>>■No103442 (くま さん) に返信
> >>2024/11/20(Wed) 16:03:36 編集(投稿者)
>> ちょっと時間が取れなくて、教えてもらったコードを今確認しましたが、両方ともエラーが出ます。
>>
>>result:10 error:
>>result:0.405465108108164 error:
>
> 動作確認していない状態でコメントします。
> 上記の「error:」の後ろに何も表示されていないという
> ことは、エラーが出ていないということではないかと思いました。
>

 ああ、ごめんなさい。数値を見逃していました。お恥ずかしい(笑)。
解決済み
[ 親 103439 / □ Tree ] 返信 編集キー/


管理者用

- Child Tree -