Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tylerbrinkley/genumerics
Genumerics is a high-performance .NET library for generic numeric operations
https://github.com/tylerbrinkley/genumerics
csharp dotnet dotnet-core generic numeric
Last synced: 2 months ago
JSON representation
Genumerics is a high-performance .NET library for generic numeric operations
- Host: GitHub
- URL: https://github.com/tylerbrinkley/genumerics
- Owner: TylerBrinkley
- License: mit
- Created: 2019-07-09T18:54:55.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2021-03-26T14:00:17.000Z (over 3 years ago)
- Last Synced: 2024-10-01T17:43:28.468Z (3 months ago)
- Topics: csharp, dotnet, dotnet-core, generic, numeric
- Language: C#
- Homepage:
- Size: 199 KB
- Stars: 19
- Watchers: 5
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
![GitHub last commit (master)](https://img.shields.io/github/last-commit/TylerBrinkley/Genumerics/master.svg?logo=github)
[![NuGet Version](https://img.shields.io/nuget/v/Genumerics.svg?logo=nuget)](https://www.nuget.org/packages/Genumerics/)
[![NuGet Downloads](https://img.shields.io/nuget/dt/Genumerics.svg?logo=nuget)](https://www.nuget.org/packages/Genumerics/)# Genumerics
Genumerics is a high-performance .NET library for generic numeric operations. It is compatible with .NET Framework 4.5+ and .NET Standard 2.0+.## The Problem
You may have come across while working in .NET where you would like to perform numeric operations over a generic numeric type. Unfortunately .NET doesn't provide a way to do that natively.This library fills that gap by providing most standard numeric operations for the following built-in numeric types and their nullable equivalents with the ability to add support for other numeric types.
`sbyte`, `byte`, `short`, `ushort`, `int`, `uint`, `long`, `ulong`, `float`, `double`, `decimal`, `nint`, `nuint`, and `BigInteger`
## Genumerics Demo
Below is a demo of some basic uses of Genumerics in the form of unit tests.
```c#
using Genumerics;
using NUnit.Framework;public class GenumericsDemo
{
[TestCase(4, 5, 9)]
[TestCase(2.25, 6.75, 9.0)]
public void Add(T left, T right, T expected)
{
Assert.AreEqual(expected, Number.Add(left, right));
Assert.AreEqual(expected, AddWithOperator(left, right));
}private T AddWithOperator(Number left, Number right) => left + right;
[TestCase(9, 6, true)]
[TestCase(3.56, 4.07, false)]
public void GreaterThan(T left, T right, bool expected)
{
Assert.AreEqual(expected, Number.GreaterThan(left, right));
Assert.AreEqual(expected, GreaterThanWithOperator(left, right));
}private bool GreaterThanWithOperator(Number left, Number right) => left > right;
[TestCase(4, 4.0)]
[TestCase(27.0, 27)]
public void Convert(TFrom value, TTo expected)
{
Assert.AreEqual(expected, Number.Convert(value));
Assert.AreEqual(expected, Number.Create(value).To());
}[TestCase("98765", 98765)]
[TestCase("12.3456789", 12.3456789)]
public void Parse(string value, T expected)
{
Assert.AreEqual(expected, Number.Parse(value));
}[TestCase(123, null, "123")]
[TestCase(255, "X", "FF")]
public void ToString(T value, string? format, string expected)
{
Assert.AreEqual(expected, Number.ToString(value, format));
}[TestCase(sbyte.MaxValue)]
[TestCase(float.MaxValue)]
public void MaxValue(T expected)
{
Assert.AreEqual(expected, Number.MaxValue());
}
}
```## Performance Comparison
The summation algorithms below were benchmarked in .NET Core 3.0 and .NET 4.8 to determine the relative performance of the library compared with an `int` specific algorithm. As can be seen in the results, the performance is equivalent.### Results
| Method | Mean | Error | StdDev | Ratio |
|----------- |-----------:|--------:|--------:|------:|
| Sum | 531.0 ns | 1.40 ns | 1.31 ns | 1.00 |
| SumNumber | 521.2 ns | 1.41 ns | 1.32 ns | 0.98 |
| SumNumber2 | 531.7 ns | 0.81 ns | 0.76 ns | 1.00 |
| SumAdd | 530.1 ns | 1.04 ns | 0.97 ns | 1.00 |
| SumAdd2 | 532.2 ns | 1.60 ns | 1.33 ns | 1.00 |### Code
```c#
using System;
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Running;
using Genumerics;public class Program
{
static void Main() => BenchmarkRunner.Run>();
}[SimpleJob(RuntimeMoniker.Net461), SimpleJob(RuntimeMoniker.NetCoreApp30), LegacyJitX86Job]
public class SumBenchmarks
where TNumericOperations : struct, INumericOperations
{
private int[] _intItems;
private T[] _items;[Benchmark(Baseline = true)]
public int Sum()
{
int sum = 0;
foreach (int item in _intItems)
{
sum += item;
}
return sum;
}[Benchmark]
public T SumNumber()
{
Number sum = default;
foreach (T item in _items)
{
sum += item;
}
return sum;
}[Benchmark]
public T SumNumber2()
{
Number sum = default;
foreach (T item in _items)
{
sum += item;
}
return sum;
}[Benchmark]
public T SumAdd()
{
T sum = default;
foreach (T item in _items)
{
sum = Number.Add(sum, item);
}
return sum;
}[Benchmark]
public T SumAdd2()
{
T sum = default;
TNumericOperations operations = default;
foreach (T item in _items)
{
sum = operations.Add(sum, item);
}
return sum;
}[GlobalSetup]
public void Setup()
{
_intItems = new int[1000];
_items = new T[1000];
Random rand = new Random();
for (int i = 0; i < 1000; ++i)
{
int value = rand.Next(10);
_intItems[i] = value;
_items[i] = Number.Create(value).To();
}
}
}
```## Interface
See [fuget](https://www.fuget.org/packages/Genumerics/1.0.2/lib/netcoreapp3.0/Genumerics.dll/Genumerics/Number) for exploring the interface.