FastDecimal 1.0.1

dotnet add package FastDecimal --version 1.0.1
                    
NuGet\Install-Package FastDecimal -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="FastDecimal" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="FastDecimal" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="FastDecimal" />
                    
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 FastDecimal --version 1.0.1
                    
#r "nuget: FastDecimal, 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 FastDecimal@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=FastDecimal&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=FastDecimal&version=1.0.1
                    
Install as a Cake Tool

FastDecimal

FastDecimal is a fast, fixed-point decimal type with strongly typed, configurable precision for .NET.

FastDecimal uses generics to configure the precision, so the precision is part of the type. If you for example want a 64-bit decimal with six fractional digits you will declare it as FastDecimal64<Six>. This allows the JIT compiler to output custom assembly code tailored to this precision.

Usage

FastDecimal comes in a 32-bit and a 64-bit variant, FastDecimal32<T> and FastDecimal64<T>. FastDecimal has the same range as the underlying integer, eg. -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 for FastDecimal64 and the generic parameter decides where the decimal point is, so for example FastDecimal64<Four> will have four fractional digits and a range from -922,337,203,685,477.5808 to 922,337,203,685,477.5807.

Creating instances

The simplest way to initialize a FastDecimal is to construct it from a decimal:

FastDecimal64<Four> price = new (23.54m);

FastDecimal implements IParsable and ISpanParsable, so you can create a FastDecimal from a string or directly in a deserializer:

var price = FastDecimal64<Four>.Parse("23.54", NumberFormatInfo.InvariantInfo);

Calculations

For doing calculations, FastDecimal implements INumber, so most operations that you would need for a numeric type will work:

var price = new FastDecimal64<Four>(23.54m);
var quantity = new FastDecimal64<Four>(5m);
var commission = new FastDecimal64<Four>(0.20m);
var totalCost = price * quantity + commission;

Checked/unchecked operations

FastDecimal implements both checked and unchecked operators. By default operators are unchecked, but if you want arithmetic operations to throw an OverflowException, when the result would overflow, then you can use a checked statement:

var value = checked(FastDecimal64<Four>.MaxValue++) // will throw OverflowException

This behavior is different from decimal which will always throw an OverflowException when an operation results in an overflow.

Rounding

When doing multiplication and division the result might have more fractional digits, than the input numbers, e.g. 2.5 * 0.1 = 0.25. If the result of a calculation cannot be represented exactly then FastDecimal will by default round to the nearest number and if the number is halfway between two numbers it will round to the nearest even number:

var a = new FastDecimal64<One>(2.5m);
var b = new FastDecimal64<One>(0.1m);
var c = a * b; // c will be 0.2 because it is the nearest even number

This is known as banker's rounding and is also the default behavior for decimal and IEEE 754 floating point numbers such as float and double.

If you want to use a different rounding mode FastDecimal provides methods where you can provide the rounding mode as a parameter:

var a = new FastDecimal64<One>(2.5m);
var b = new FastDecimal64<One>(0.1m);
var c = FastDecimal64<One>.Multiply(a, b, MidpointRounding.AwayFromZero); // c will be 0.3 because it rounds away from zero

Performance

The main reason to use FastDecimal over the built-in decimal type is for performance since decimal strictly can represent more values than FastDecimal64. But if you don't need the range offered by decimal, then FastDecimal can be a lot faster!

The arithmetic operations in FastDecimal are written to be highly performant, and in general, FastDecimal should be faster than decimal. To get an idea of the performance difference between FastDecimal and decimal you can take a look at the benchmarks.

FastDecimal64 and FastDecimal32 are approximately equally fast (on 64-bit systems) when doing the same calculations, but FastDecimal32 takes up less memory, so it might be a good choice if you are allocating a lot of objects with decimal values, e.g. if you are getting thousands of price updates per second.

And casting from FastDecimal32 to FastDecimal64 is extremely fast, so you can easily use FastDecimal32 for storage and FastDecimal64 for doing calculations.

Comparison with decimal

decimal FastDecimal64 FastDecimal32
Integer range -79,228,162,514,264,337,593,543,950,335 - 79,228,162,514,264,337,593,543,950,335 -9,223,372,036,854,775,808 - 9,223,372,036,854,775,807 -2,147,483,648 - 2,147,483,647
Scaling factor 0 - 28 0 - 19 0 - 9
Size 128 bit 64 bit 32 bit
Product Compatible and additional computed target framework versions.
.NET net7.0 is compatible.  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 is compatible.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net7.0

    • No dependencies.
  • net8.0

    • No dependencies.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 191 5/27/2024
1.0.0 175 5/26/2024