fin_decimal - Rust High-Performance Decimal Fixed-point Arithmetic
fin_decimal is a high-performance, #![no_std] compatible decimal fixed-point library tailored specifically for financial and tax computations.
Unlike arbitrary-precision "big decimal" libraries that are slow and heap-allocate, or standard floating-point numbers (f32/f64) which suffer from rounding errors and precision loss, fin_decimal operates on an implicit scaling factor over a standard 64-bit signed integer (i64).
This means additions and subtractions compile down to single, lightning-fast native CPU instructions, while multiplications and divisions utilize 128-bit math (with platform-specific inline assembly on x86_64) to guarantee strictly compliant decimal rounding without floating-point artifacts.
Features
- Const Generics (
Decimal<const DIGITS: u8>): Zero-cost abstraction over multiple precision types. Amount64(4 Decimal Digits): The standard precision for accounting, monetary amounts, and ledgers (up to ~±922 billion).Rate64(8 Decimal Digits): A higher-precision type used for exact forex/exchange rates and interest calculations.- Strict Rounding Modes: Explicit
.round_to(mode),.mul_rounded(), and.div_rounded()methods to ensure compliance with arbitrary tax codes (e.g.HalfUp,HalfEvenBanker's Rounding,Down,Up). - Checked Math: Built-in methods like
.checked_add()to prevent overflow panics in mission-critical applications. - Serde Support: Optional string-based JSON serialization via the
serdefeature, preventing transit precision loss over REST APIs. no_stdEnvironment Support: Works gracefully in embedded contexts or core-only systems.
Getting Started
Add fin_decimal to your Cargo.toml. To enable JSON serialization, include the serde feature:
[]
= { = "0.1", = ["serde"] }
Basic Usage
The library provides trait overloads, so the standard +, -, *, /, and % operators work ergonomically alongside native primitives. By default, standard multiplication and division utilize standard "Half-Up" financial rounding.
use Amount64;
use FromStr;
Explicit Rounding & Compliance
When calculating taxes or complex financial algorithms, regulations often dictate exact rounding constraints. Use the Rounding enum to dictate exactly how calculations terminate.
use ;
Safety and Overflow (Checked Math)
Because Amount64 is backed by a 64-bit integer, values exceeding ~922,337,203,685 (for 4 decimal digits) will wrap or panic in debug mode depending on your build settings.
For robust backends, always use the checked_* routines to gracefully handle theoretical overflows:
use Amount64;
Exchange Rates (Rate64)
If you are dealing with fractional percentages or Forex multi-currency pipelines, 4 decimal places is rarely enough. The Rate64 type provides 8 decimal places of precision automatically.
use ;
Why Not f64 or Big Numbers?
- Floating Point (
f64): Floats cannot perfectly represent base-10 decimals.0.1 + 0.2famously equals0.30000000000000004in floating-point math, violating strict accounting properties. - Big Numbers (e.g.
num-bigintorrust-decimal): These libraries perform heap allocations on virtually every math operation and represent numbers internally as slow arrays orVecs.fin_decimalrelies purely oni64CPU registers, making it orders of magnitude faster. - The Sweet Spot: The ±9.22 trillion limit of
Amount64is vastly more than sufficient for 99% of general ledger entries, eCommerce carts, and standard banking, while reaping the ultimate performance benefits of fixed-width hardware math.