This library is an opinionated port of the Java Math package provided as part of the Apache Harmony framework (now defunct), that can be used to handle big numbers and decimals in .NET applications.
At the time of the development of this library, the .NET framework did not provide a native support for big numbers and decimals, and not even the System.Numerics namespace was available yet, which was limiting the operations that could be performed on big numbers.
In fact, during the development of the DeveelDB database engine, we needed a library that could handle big numbers and decimals in a more flexible way, and that could be used in a cross-platform environment.
Still today, the .NET framework does not provide a native support for big decimals, and the System.Numerics namespace is still limited to handling operations on big integers.
This is a little effort to address this gap, providing the community with a library that can be used to handle big numbers and decimals in a more flexible way.
It doesn't have any ambition to replace the System.Numerics namespace, but it can be used as a complement to it, especially when dealing with big decimals.
Given the limited knowledge of the author in the field of numerical analysis, the library is subject to reviews and any contribution to improve the quality of the code is welcome.
using Deveel.Math;
// Precise currency calculation with controlled rounding
var price = BigDecimal.Parse("19.99");
var quantity = new BigDecimal(3);
var taxRate = BigDecimal.Parse("0.0875"); // 8.75% tax
var subtotal = price * quantity;
var tax = (subtotal * taxRate).ScaleTo(2, RoundingMode.HalfUp); // Round tax to 2 decimals
var total = subtotal + tax;
Console.WriteLine($"Subtotal: {subtotal.ToString("P")}"); // 59.97
Console.WriteLine($"Tax: {tax.ToString("P")}"); // 5.25
Console.WriteLine($"Total: {total.ToString("P")}"); // 65.22using Deveel.Math;
// Working with numbers beyond long.MaxValue
var a = BigInteger.Parse("123456789012345678901234567890");
var b = BigInteger.Parse("987654321098765432109876543210");
var product = a * b;
var gcd = BigMath.Gcd(a, b);
var isPrime = BigInteger.IsProbablePrime(a, 100);
Console.WriteLine($"Product: {product}");
Console.WriteLine($"GCD: {gcd}");
Console.WriteLine($"Is 'a' probably prime? {isPrime}");For detailed documentation, see the docs folder:
| Topic | Description |
|---|---|
| Getting Started | Overview, installation, and quick start |
| BigDecimal | Creation, parsing, conversion, operators, arithmetic, scale & precision, formatting |
| BigInteger | Creation, parsing, conversion, operators, arithmetic, modular math, bit operations, primality |
| MathContext & RoundingMode | Precision control, rounding strategies, predefined contexts |
| Advanced Math Operations | BigMath static class, advanced division, powers, random generation |
| Interoperability | BigInteger vs System.Numerics, type conversions, primitive conversions, parsing |
Deveel Math has been benchmarked against .NET built-in types across .NET 6.0 through 10.0. Key results on .NET 10.0:
| Area | Result |
|---|---|
| BigDecimal arithmetic | 27-119 ns per operation (vs 1-47 ns for decimal), with 46-55% improvement from .NET 6.0 to 10.0 |
| BigInteger arithmetic | Competitive with System.Numerics.BigInteger; faster at division and 1024-bit+ multiplication |
| BigInteger ModPow | Up to 5.6x faster than System.Numerics at 512-bit |
| BigInteger parsing | 2.3x faster for large numbers (500 digits) |
| Memory allocations | Higher than native types (96 B - 24 KB per operation), but acceptable for arbitrary-precision workloads |
For detailed benchmark tables and analysis, see Performance Benchmarks.
The library is available as a NuGet package, and it can be installed in any .NET application that supports .NET 8.0, .NET 9.0, or .NET 10.0.
The binaries are available in two deployment streams:
| Type | Source | Package |
|---|---|---|
| Stable | NuGet | |
| Pre-Release | GitHub |
To install the dmath library you can use the following command from the NuGet Package Manager Console on the root of your project:
PM> Install-Package dmath
or rather using the dotnet CLI:
$ dotnet add package dmath
Deveel Math includes its own BigInteger implementation alongside BigDecimal. While .NET provides System.Numerics.BigInteger, Deveel.Math's BigInteger exists primarily to support BigDecimal (which .NET does not provide) and to maintain Java-compatible behavior.
Key differences:
- Internal representation: Deveel.Math uses sign + magnitude;
System.Numericsuses two's complement - BigDecimal integration: Deveel.Math.BigInteger is the native unscaled value type for BigDecimal
- Java compatibility: Results match Java's
java.mathpackage semantics - Additional features: Primality testing (
IsProbablePrime,NextProbablePrime), modular inverse (ModInverse), radix-based parsing (base 2-36)
When to use which:
- Use Deveel.Math.BigInteger when working with
BigDecimal, when you need Java-compatible results, or when using Deveel ecosystem libraries - Use System.Numerics.BigInteger when your codebase already uses it or when interoperating with third-party libraries that expect it
Converting between them is straightforward:
// Deveel.Math -> System.Numerics (implicit)
System.Numerics.BigInteger sys = deveelMathBI;
// System.Numerics -> Deveel.Math (explicit)
var deveel = (BigInteger)sys;
// or
var deveel = BigInteger.FromSystemBigInteger(sys);For a complete guide, see the Interoperability documentation.
The BigDecimal class represents a big decimal number that can be used to perform arithmetic operations with arbitrary precision.
The class provides a set of methods to perform arithmetic operations, such as addition, subtraction, multiplication, division, and rounding.
To create a new BigDecimal instance, you can use one of the following constructors:
// Creating an instance from an integer
var number = new BigDecimal(1234567890);
// Creating an instance from a long integer
var number = new BigDecimal(1234567890L);
// Creating an instance from a double
var number = new BigDecimal(1234567890.123456);or rather from a string:
// Parsing a string to a big decimal
var number = BigDecimal.Parse("1234567890");The BigInteger class represents an arbitrary-precision integer. It was originally ported from Apache Harmony but is now retained for compatibility and extended functionality beyond System.Numerics.BigInteger.
The MathContext class encapsulates settings that describe the number of digits and the rounding algorithm to be used for BigDecimal operations. The RoundingMode enumeration specifies the rounding behavior for operations that require rounding.
- .NET 8.0, 9.0, or 10.0 SDK
- xUnit v3 test runner (included in the test project)
# Restore dependencies
dotnet restore
# Build the solution
dotnet build
# Run tests
dotnet test
# Run tests with code coverage (generates Cobertura report)
dotnet test -- --coverage --coverage-output-format coberturaThe project uses GitHub Actions for continuous integration:
- Build Matrix: Tests run on .NET 8.0, 9.0, and 10.0 across Ubuntu, Windows, and macOS
- Code Coverage: Reports are published to Codecov
- Versioning: Uses GitVersion for semantic versioning
- Publishing: Pre-release packages are published to GitHub Packages; stable releases to NuGet
If you want to contribute to the development of this library, you can fork the repository and submit a pull request with your changes.
Please make sure to follow the coding style and conventions used in the project, and to provide a clear description of the changes you are proposing.
Thanks to everyone who has contributed to Deveel Math:
The library is released under the terms of the Apache License 2.0, and it is provided as-is without any warranty or support.