NCalc.NetCore
1.0.1
dotnet add package NCalc.NetCore --version 1.0.1
NuGet\Install-Package NCalc.NetCore -Version 1.0.1
<PackageReference Include="NCalc.NetCore" Version="1.0.1" />
<PackageVersion Include="NCalc.NetCore" Version="1.0.1" />
<PackageReference Include="NCalc.NetCore" />
paket add NCalc.NetCore --version 1.0.1
#r "nuget: NCalc.NetCore, 1.0.1"
#:package NCalc.NetCore@1.0.1
#addin nuget:?package=NCalc.NetCore&version=1.0.1
#tool nuget:?package=NCalc.NetCore&version=1.0.1
NCalc.NetCore
NCalc.NetCore is a fast, lightweight, and extensible mathematical and logical expression evaluator for .NET.
Targeting .NET Standard 2.0, it runs seamlessly across modern .NET runtimes (.NET 6, 7, 8, 9, 10), .NET Core 2.0+, and .NET Framework 4.6.1+.
It allows developers to parse, compile, and dynamically evaluate expressions at runtime with parameter substitution, custom functions, vector operations, and high-performance in-memory caching.
Table of Contents
Features
- Full Mathematical Capabilities: Arithmetic operations, powers, roots, trigonometry, logarithms, and scientific notation.
- Precision Preservation: Smart numeric coercion supporting
decimal,double,float,long, andintwithout silent loss of precision. - Rich Boolean & Relational Logic: Short-circuit evaluation (
&&,||,and,or,not), comparisons (==,!=,<,<=,>,>=), and ternary logic (? :). - Built-in Functions: Core mathematical functions plus control-flow functions like
if(...)and membership testin(...). - Dynamic Extensibility: Subscribe to
EvaluateFunctionandEvaluateParameterevents to hook custom functions and resolve variables on demand. - High Performance Caching: Automatic thread-safe parsed expression cache utilizing weak references to avoid redundant parsing overhead.
- Batch / Vector Operations: Evaluate an expression across arrays of parameters simultaneously with
EvaluateOptions.IterateParameters. - Pre-evaluation Syntax Checking: Validate expression grammar prior to execution using
HasErrors(). - No External Dependencies (outside ANTLR): Lightweight and self-contained.
Installation
Install the package via NuGet:
.NET CLI
dotnet add package NCalc.NetCore
Package Manager Console
Install-Package NCalc.NetCore
PackageReference
<PackageReference Include="NCalc.NetCore" Version="1.0.1" />
Quick Start
using System;
using NCalc;
// 1. Simple arithmetic
var expr1 = new Expression("2 * (3 + 5)");
Console.WriteLine(expr1.Evaluate()); // 16
// 2. Parameters
var expr2 = new Expression("[radius] * [radius] * [pi]");
expr2.Parameters["radius"] = 5;
expr2.Parameters["pi"] = Math.PI;
Console.WriteLine(expr2.Evaluate()); // 78.5398...
// 3. Conditionals
var expr3 = new Expression("if(score >= 70, 'Passed', 'Failed')");
expr3.Parameters["score"] = 85;
Console.WriteLine(expr3.Evaluate()); // "Passed"
Usage Guide
Basic Arithmetic & Calculations
Standard operator precedence applies (parentheses, multiplication/division, addition/subtraction):
var expression = new Expression("1 + 2 + 3 * 4 / 2");
var result = expression.Evaluate(); // 9.0
Scientific notation is natively supported:
var expression = new Expression("1.22e1 + 1e2");
var result = expression.Evaluate(); // 112.2
Working with Parameters
Parameters can be enclosed in square brackets [parameter] or used directly by identifier name if they follow standard naming conventions:
var expr = new Expression("([UnitPrice] * [Quantity]) * (1 - [Discount])");
expr.Parameters["UnitPrice"] = 29.99m;
expr.Parameters["Quantity"] = 3;
expr.Parameters["Discount"] = 0.10m;
decimal total = (decimal)expr.Evaluate();
Nested Sub-expressions
Parameters can themselves be other Expression objects. They will be evaluated recursively:
var volumeExpr = new Expression("[Area] * [Height]");
var areaExpr = new Expression("[Width] * [Length]");
areaExpr.Parameters["Width"] = 5;
areaExpr.Parameters["Length"] = 10;
volumeExpr.Parameters["Area"] = areaExpr;
volumeExpr.Parameters["Height"] = 2;
Console.WriteLine(volumeExpr.Evaluate()); // 100
Dynamic Parameters via Events
If you have lazy-loaded or context-dependent variables that should only be fetched if the expression reaches them, subscribe to the EvaluateParameter event:
var expr = new Expression("if([UserIsAdmin], [SecretKey], 'Access Denied')");
expr.EvaluateParameter += (name, args) =>
{
if (name == "UserIsAdmin")
{
args.Result = CurrentUser.IsAdmin();
}
else if (name == "SecretKey")
{
args.Result = Vault.GetSecretKey(); // Only evaluated if condition is true!
}
};
var output = expr.Evaluate();
Custom Functions
Extend NCalc with your own business logic or custom domain methods using the EvaluateFunction event:
var expr = new Expression("SecretOperation(5, 10) + 1");
expr.EvaluateFunction += (name, args) =>
{
if (string.Equals(name, "SecretOperation", StringComparison.OrdinalIgnoreCase))
{
int a = Convert.ToInt32(args.Parameters[0].Evaluate());
int b = Convert.ToInt32(args.Parameters[1].Evaluate());
args.Result = (a * b) + 42;
}
};
Console.WriteLine(expr.Evaluate()); // (5 * 10) + 42 + 1 = 93
Note:
args.Parameters[i]yields anExpressioninstance. This allows parameters to be evaluated lazily, avoiding redundant calculations if the function does not need all arguments.
Conditionals and Flow Control
if(condition, thenValue, elseValue)
Short-circuit evaluation is guaranteed: the inactive branch is not executed, preventing unintended side effects or division-by-zero exceptions.
var expr = new Expression("if([divider] != 0, [total] / [divider], 0)");
expr.Parameters["divider"] = 0;
expr.Parameters["total"] = 100;
Console.WriteLine(expr.Evaluate()); // 0 (no DivideByZeroException!)
Ternary Operator condition ? thenValue : elseValue
var expr = new Expression("score > 50 ? 'Pass' : 'Fail'");
expr.Parameters["score"] = 75;
Console.WriteLine(expr.Evaluate()); // "Pass"
in(value, item1, item2, ...)
Evaluates whether a value exists within a given sequence:
var expr = new Expression("in([status], 'Pending', 'InReview', 'Approved')");
expr.Parameters["status"] = "Approved";
Console.WriteLine(expr.Evaluate()); // true
Vector Evaluation (IterateParameters)
When calculating results over large arrays or data sets, enable EvaluateOptions.IterateParameters. NCalc will evaluate the compiled syntax tree across corresponding items in collections:
var expr = new Expression("[x] * [y]", EvaluateOptions.IterateParameters);
expr.Parameters["x"] = new[] { 1, 2, 3, 4, 5 };
expr.Parameters["y"] = new[] { 10, 20, 30, 40, 50 };
var results = (IList)expr.Evaluate();
// results contains: [10, 40, 90, 160, 250]
All
IEnumerableparameters passed under this mode must contain the same number of elements.
Syntax Checking and Error Handling
You can validate expression syntax without executing the expression:
var expr = new Expression("2 * (5 +");
if (expr.HasErrors())
{
Console.WriteLine($"Syntax Error: {expr.Error}");
}
else
{
var result = expr.Evaluate();
}
If an invalid expression is evaluated directly, an EvaluationException is thrown:
try
{
new Expression("4. + 2").Evaluate();
}
catch (EvaluationException ex)
{
Console.WriteLine($"Evaluation failed: {ex.Message}");
}
Data Types and Literals
| Type | Literal Example | Notes |
|---|---|---|
| Integer / Real | 123, 123.456, 1e5, .1e-2 |
Automatically coerced to the most precise type. |
| String | 'hello', 'it\'s fine' |
Single-quoted. Supports escape sequences and Unicode (\u0048). |
| Boolean | true, false, True, False |
Case-insensitive boolean literals. |
| Date | #2026/12/31#, #01/15/2026 14:30:00# |
Enclosed between hash signs (#...#), parsed as DateTime. |
Date Comparisons
var expr = new Expression("#2026-10-22# >= #2026-01-01#");
Console.WriteLine(expr.Evaluate()); // true
String Concatenation
The + operator concatenates if either operand is a string:
var expr = new Expression("'Hello ' + [Name]");
expr.Parameters["Name"] = "World";
Console.WriteLine(expr.Evaluate()); // "Hello World"
Cache Management
NCalc automatically compiles expressions into an Abstract Syntax Tree (AST) and caches them in memory using WeakReference to maximize execution speed while avoiding memory leaks.
// Disable caching globally if needed:
Expression.CacheEnabled = false;
// Or disable cache for a single expression instance:
var expr = new Expression("2 + 2", EvaluateOptions.NoCache);
Case Sensitivity
By default, NCalc enforces case sensitivity for functions and parameters. Use EvaluateOptions.IgnoreCase to match case-insensitively:
var expr = new Expression("abs([MyParam])", EvaluateOptions.IgnoreCase);
expr.Parameters["myparam"] = -42;
Console.WriteLine(expr.Evaluate()); // 42
Rounding Options
Standard .NET Math.Round defaults to banker's rounding (round to nearest even). If you require arithmetic rounding away from zero (halfway rounded away from zero), pass EvaluateOptions.RoundAwayFromZero:
var expr = new Expression("Round(22.5, 0)", EvaluateOptions.RoundAwayFromZero);
Console.WriteLine(expr.Evaluate()); // 23 (instead of 22)
Reference Tables
Built-in Functions
| Function | Signature | Description |
|---|---|---|
Abs |
Abs(x) |
Returns the absolute value of x. |
Acos |
Acos(x) |
Returns the angle whose cosine is x. |
Asin |
Asin(x) |
Returns the angle whose sine is x. |
Atan |
Atan(x) |
Returns the angle whose tangent is x. |
Ceiling |
Ceiling(x) |
Returns the smallest integer greater than or equal to x. |
Cos |
Cos(x) |
Returns the cosine of the specified angle. |
Exp |
Exp(x) |
Returns e raised to the specified power. |
Floor |
Floor(x) |
Returns the largest integer less than or equal to x. |
IEEERemainder |
IEEERemainder(x, y) |
Returns the remainder resulting from the division of a specified number by another. |
Log |
Log(x, base) |
Returns the logarithm of x in a specified base. |
Log10 |
Log10(x) |
Returns the base-10 logarithm of x. |
Max |
Max(a, b) |
Returns the larger of two numbers. |
Min |
Min(a, b) |
Returns the smaller of two numbers. |
Pow |
Pow(x, y) |
Returns a specified number raised to the specified power. |
Round |
Round(x, decimals) |
Rounds a value to a specified number of fractional digits. |
Sign |
Sign(x) |
Returns an integer indicating the sign of a number (-1, 0, or 1). |
Sin |
Sin(x) |
Returns the sine of the specified angle. |
Sqrt |
Sqrt(x) |
Returns the square root of a specified number. |
Tan |
Tan(x) |
Returns the tangent of the specified angle. |
Truncate |
Truncate(x) |
Calculates the integral part of a number. |
if |
if(cond, then, else) |
Conditional evaluation with short-circuit behavior. |
in |
in(item, val1, val2, ...) |
Checks if item matches any subsequent values in the argument list. |
Supported Operators
| Category | Operators | Description / Examples |
|---|---|---|
| Arithmetic | +, -, *, /, % |
Addition, subtraction, multiplication, division, modulo. |
| Relational | ==, =, !=, <>, <, <=, >, >= |
Equality and comparison tests. (= is an alias for ==, <> for !=). |
| Logical | &&, and, \|\|, or, !, not |
Logical conjunction, disjunction, and negation. |
| Conditional | ? : |
Ternary conditional operator (condition ? trueExpr : falseExpr). |
| Bitwise | &, \|, ^, ~, <<, >> |
Bitwise AND, OR, XOR, NOT, left shift, and right shift. |
Evaluation Options
Available through the EvaluateOptions bitwise enum:
| Flag | Value | Description |
|---|---|---|
EvaluateOptions.None |
1 |
Default behavior. Caching enabled, case-sensitive. |
EvaluateOptions.IgnoreCase |
2 |
Case-insensitive matching for identifiers, parameters, and function names. |
EvaluateOptions.NoCache |
4 |
Ignores cached ASTs and does not store the compiled expression in the cache. |
EvaluateOptions.IterateParameters |
8 |
Evaluates array parameters iteratively and returns an IList of results. |
EvaluateOptions.RoundAwayFromZero |
16 |
Modifies Round() behavior to round midpoint values away from zero. |
Compatibility
NCalc.NetCore targets .NET Standard 2.0, providing broad compatibility across runtimes:
- .NET (Modern): .NET 6.0, .NET 7.0, .NET 8.0, .NET 9.0, .NET 10.0+
- .NET Core: .NET Core 2.0, 2.1, 3.0, 3.1
- .NET Framework: .NET Framework 4.6.1, 4.6.2, 4.7.x, 4.8.x
- Mono / Xamarin / Unity: Any platform implementing .NET Standard 2.0.
License & Credits
This project is licensed under the terms of the MIT License.
Acknowledgments & Lineage
NCalc.NetCore is the product of continuous community development:
- Original NCalc: Created and developed by Sébastien Ros. Copyright © 2011 Sébastien Ros.
- NCalc-Edge: Forked and modernized by Peter Marx (pitermarx) and contributors. Copyright © 2016-2019 Peter Marx.
- NCalc-NetCore: Ported to .NET Core / .NET Standard by Alterdata Software and maintained by The Noobs. Copyright © 2017-2026 Alterdata Software, The Noobs and contributors.
All original copyrights and licenses are maintained in accordance with the MIT License requirements.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Antlr3.Runtime (>= 3.5.1)
NuGet packages (8)
Showing the top 5 NuGet packages that depend on NCalc.NetCore:
| Package | Downloads |
|---|---|
|
GeneticSharp.Extensions
Extensions for GeneticSharp: a fast, extensible, multi-platform and multithreading C# Genetic Algorithm library that simplifies the development of applications using Genetic Algorithms (GAs). |
|
|
Nettle.NCalc
An extension for the Nettle templating engine that provides direct integration with NCalc. |
|
|
ASTTemplateParser
High-performance AST-based template parser for .NET with HTML-like syntax, component system, block parser with mixed content support, layouts, slots, native Newtonsoft.Json support, and enterprise-grade security. Cross-platform compatible with .NET Standard 2.0, .NET Framework 4.8, .NET 6.0+, .NET 8.0+, .NET 9.0+, and .NET 10.0+. |
|
|
SuperXml.NetCore
SuperXml is just a light weight and easy to use templating engine library, useful to create string and xml templates. This is a fork from the original lib from beto-rodrigues to support .net core. |
|
|
jz.code.dotnet
简众科技(JZTECH) dotnet 统一开发包,最低要求.net6.0,仅供简众科技内部使用,请勿外传,简众科技拥有所有权利。 |
GitHub repositories (2)
Showing the top 2 popular GitHub repositories that depend on NCalc.NetCore:
| Repository | Stars |
|---|---|
|
giacomelli/GeneticSharp
GeneticSharp is a fast, extensible, multi-platform and multithreading C# Genetic Algorithm library that simplifies the development of applications using Genetic Algorithms (GAs).
|
|
|
veldlabs/miki-bot
Miki Discord Bot
|