【问题标题】:DataTable Compute Value is too large or too small for type Int32对于 Int32 类型,DataTable 计算值太大或太小
【发布时间】:2015-04-10 19:21:54
【问题描述】:

我最近遇到了一种在 C# 中计算表达式的方法,使用数据表对象的计算方法。这是一段代码:

    string expression = "330200000*450000";
    var loDataTable = new DataTable();
    var loDataColumn = new DataColumn("Eval", typeof(double), expression);
    loDataTable.Columns.Add(loDataColumn);
    loDataTable.Rows.Add(0);
    MessageBox.Show(((double)(loDataTable.Rows[0]["Eval"])).ToString()); 

如果你输入一个像“300 * 2”这样的简单表达式,这将起作用,但是返回大数字的表达式将不起作用,我收到消息:

“对于类型 'Int32',值要么太大要么太小。”

我试图强制类型加倍,但由于某种原因,错误仍然指向有关 Int32 类型的某些内容,我不确定它来自哪里。

小手吗?

【问题讨论】:

  • 您在哪一行得到异常?在第 3 行还是第 6 行?顺便说一句:为什么不使用 long 而不是 double?
  • 第 4 行出现错误:loDataTable.Columns.Add(loDataColumn);我绝对可以使用 long,但它不会改变任何东西。
  • 试着写出数字 3300000D 和 450000D。你需要声明双打像 double myVal = 3D;没有 D,它是一个整数。
  • 你为什么将它作为字符串插入?
  • 因为这是在wpf的上下文中,用户可以在文本框中输入公式,然后进行计算。

标签: c# datatable


【解决方案1】:

将“.0”附加到方程中的值:

string expression = "330200000.0*450000.0";

如果如您所说,用户已按原样输入方程式(即没有“.0”),那么您可能必须进行一些模糊不愉快的字符串操作才能实现这一点。我想出了以下内容,尽管我确信它可以做得更好:

string expression = "330200000*450000"; // or whatever your user has entered
expression = Regex.Replace(
    expression, 
    @"\d+(\.\d+)?", 
    m => {
         var x = m.ToString(); 
         return x.Contains(".") ? x : string.Format("{0}.0", x);
    }
);
var loDataTable = new DataTable();
var computedValue = loDataTable.Compute(expression, string.Empty);

正则表达式会尝试说明您的用户是否已经在其等式中的任何数字的末尾添加了小数。

【讨论】:

    【解决方案2】:
            string expression = "-2+4.00*0.20+3.000/06";
            char[] separators = new char[4] { '+', '-', '*', '/' };
            string[] numbers = expression.Split(separators, StringSplitOptions.RemoveEmptyEntries);
    
            for (int i = 0; i < numbers.Length; i++)
            {
                Regex r1 = new Regex(numbers[i]);
                expression = r1.Replace(expression, "X", 1);
            }
    
            for (int i = 0; i < numbers.Length; i++)
            {
                decimal d = Convert.ToDecimal(numbers[i]);
                numbers[i] = d.ToString("0.####");//# 0-28
                if (!numbers[i].Contains(".")) numbers[i] += ".0";
            }
    
            for (int i = 0; i < numbers.Length; i++)
            {
                Regex r2 = new Regex("X");
                expression = r2.Replace(expression, numbers[i], 1);
            }
    
            if (expression.Contains("/0.0")) return;
    
            decimal dec = Convert.ToDecimal(new DataTable().Compute(expression, ""));
            result = dec.ToString("0.####");//# 0-28
    

    【讨论】:

      猜你喜欢
      • 2013-12-18
      • 2011-09-14
      • 2017-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-09
      • 2012-08-05
      相关资源
      最近更新 更多