DataTable Compute Value слишком велико или слишком мало для типа Int32.
Недавно я нашел способ оценить выражение в C#, используя метод compute объекта с данными. Вот кусок кода:
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, что я не уверен, откуда он.
Маленькая рука на это?
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);
Регулярное выражение пытается учесть, поставил ли ваш пользователь десятичную дробь в конце любого из чисел в своем уравнении.
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