2016-03-30 17 views
4

Bir dizeyi değerlendirmek için Ncalc kullanarak genel bir hesaplama yordamımız var. Ancak, bir çarpımdaki değerler Ncalc'in onları int olarak gördüğü kadar küçük olduğu halde, sonuç bir int için çok büyük olduğunda bir problem üzerinde çalışıyoruz.NCalc türünü belirtin

Örnek:

 var expr = new NCalc.Expression("1740263 * 1234"); 
     object result = expr.Evaluate(); 
     Console.WriteLine(result.ToString()); 
     Console.ReadKey(); 

Bu olumsuz bir int değer ile sonuçlanır.

Ncalc'i hesaplama için uzun süre kullanmaya zorlamanın bir yolu var mı?

Parametreleri kullanmayı denedim ve bu çalışma ancak kodumuzun uygulanması için büyük bir yeniden yazma anlamına gelir ve mümkünse bunu önlemek isterim.

Teşekkür

cevap

2

NCalc sonra Int64 olarak hesaplanacak bir sayı zorlayamaz Int32 olarak tamsayı veri türünü kullanır. Ancak, yerleşik matematik işlevlerini kullanmıyorsanız ve düz matematiksel operatörlere güveniyorsanız, bir sayıyı long dönüştürebilir ve doğru operatörleri çağırırsınız. Şunu görelim: (long)(int)args.EvaluateParameters()[0]:

var expr = new NCalc.Expression("CLng(1740263) * 1234"); 
expr.EvaluateFunction += delegate(string name, NCalc.FunctionArgs args) 
{ 
    // Nostalgic CLng function... 
    if (String.Equals(name, "CLng", StringComparison.CurrentCultureIgnoreCase)) 
    { 
     args.HasResult = true; 
     args.Result = Convert.ToInt64(args.EvaluateParameters()[0]); 
    } 
}; 

doğrudan o zaman Convert.ToInt64() veya çift döküm kullanmak zorunda Int32 parametre Int64 için kutulu Cast olamaz unutmayın. Şimdi sonucunu kontrol edebilirsiniz doğrudur:

var result = expr.Evaluate(); 
Console.WriteLine("Result is: {0} (type {1})", 
    result, result.GetType()); 

Uygun tip dönüşüm sonra long için döküm iki değer de gerekmez gerçekleştirilir. doğrudan da nokta numaraları (NCalc içinde decimal) yüzen kullanabilir ve bu tür sorun olmaz

Not:

var expr = new NCalc.Expression("1740263.0 * 1234.0"); 
+0

için sınırların dışında olması durumunda bir hata verir. Ayrıntılı yanıtınız için teşekkür ederiz. Çok yardımcı oldu. – user2380829

0
Sen bunların yerine, dize gelen tüm sayı ayıklamak için normal ifadeler kullanabilirsiniz

parametrelerle ve daha sonra parametreleri dönüştürülen sayılara ayarlayın. Bu örnekte, int sayısının ondalık sayıya dönüştürülmesini istiyorum.

string myCalculationString = "1000000 * 10000000"; 
striny myPattern = @"-?\d+(,\d+)*(\.\d+(e\d+)?)?"; 

MatchCollection matches = 
Regex.Matches(convertedCalculation, myPattern); 

int matchCount = 0; 
convertedCalculation = Regex.Replace(convertedCalculation, 
myPattern , m => "[p" + matchCount++ + "]"); 

for (int i = 0; i < matches.Count; i++) 
    { 
     Match match = matches[i]; 
     decimal number = Convert.ToDecimal(match.Value); 
     expression.Parameters.Add($"p{i}", number); 
    } 

decimal result = (decimal)expression.Evaluate(); 

Not ben de normal ifade test değil ama pozitif/negatif sayılar için iş gibi görünüyor ve isteğe bağlı ondalık noktayı sağlar. Ayrıca, sayılardan veya sonuçlardan herhangi birinin ondalık