NCalc.NetCore 1.0.1

dotnet add package NCalc.NetCore --version 1.0.1
                    
NuGet\Install-Package NCalc.NetCore -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="NCalc.NetCore" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="NCalc.NetCore" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="NCalc.NetCore" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add NCalc.NetCore --version 1.0.1
                    
#r "nuget: NCalc.NetCore, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package NCalc.NetCore@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=NCalc.NetCore&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=NCalc.NetCore&version=1.0.1
                    
Install as a Cake Tool

NCalc.NetCore

NuGet NuGet Downloads License: MIT Target: .NET Standard 2.0

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, and int without 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 test in(...).
  • Dynamic Extensibility: Subscribe to EvaluateFunction and EvaluateParameter events 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 an Expression instance. 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 IEnumerable parameters 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 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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

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
Version Downloads Last Updated
1.0.1 612,507 11/10/2017
1.0.0 6,054 1/31/2017