Expand description
§nvana_fixed
A high-precision fixed-point arithmetic library for Rust, designed for financial and DeFi calculations where precision is critical.
This crate provides the PreciseNumber type, which uses a fixed-point representation
with 18 decimal places (10^18 scaling factor) internally backed by a 256-bit integer.
This allows for precise decimal arithmetic without floating-point errors, making it
ideal for financial applications, smart contracts, and DeFi protocols.
§Features
- High Precision: 18 decimal places of precision (WAD format)
- Large Range: Uses U256 internally, supporting values much larger than u128
- Safe Arithmetic: All operations are checked and return
Optionon overflow/underflow - DeFi Ready: Built-in support for basis points and micro basis points
- Zero-Cost Abstractions: Efficient operations with rounding corrections
- Comparison Traits: Full support for equality and ordering operations
§Examples
§Basic arithmetic
use nvana_fixed::PreciseNumber;
let a = PreciseNumber::new(10).unwrap();
let b = PreciseNumber::new(3).unwrap();
// Addition
let sum = a.checked_add(&b).unwrap();
assert_eq!(sum.to_imprecise().unwrap(), 13);
// Multiplication
let product = a.checked_mul(&b).unwrap();
assert_eq!(product.to_imprecise().unwrap(), 30);
// Division with rounding
let quotient = a.checked_div(&b).unwrap();
assert_eq!(quotient.to_imprecise().unwrap(), 3); // 10/3 = 3.333... rounds to 3§Working with percentages
use nvana_fixed::PreciseNumber;
// Using basis points (1% = 100 basis points)
let rate = PreciseNumber::from_basis_points(500).unwrap(); // 5%
let principal = PreciseNumber::new(1000).unwrap();
let interest = principal.checked_mul(&rate).unwrap();
assert_eq!(interest.to_imprecise().unwrap(), 50); // 5% of 1000
// Using micro basis points for finer precision (1% = 10,000 micro basis points)
let fine_rate = PreciseNumber::from_micro_basis_points(12_500).unwrap(); // 1.25%
let fine_interest = principal.checked_mul(&fine_rate).unwrap();
assert_eq!(fine_interest.to_imprecise().unwrap(), 13); // 1.25% of 1000 = 12.5, rounds to 13§Comparisons
use nvana_fixed::PreciseNumber;
let a = PreciseNumber::new(100).unwrap();
let b = PreciseNumber::new(200).unwrap();
assert!(a < b);
assert!(b > a);
assert_eq!(a, a);
assert_ne!(a, b);§Working with fractional values
use nvana_fixed::PreciseNumber;
// Create from raw scaled value (already multiplied by 10^18)
let half = PreciseNumber::from_scaled(500_000_000_000_000_000); // 0.5
let two = PreciseNumber::new(2).unwrap();
let result = half.checked_mul(&two).unwrap();
assert_eq!(result.to_imprecise().unwrap(), 1); // 0.5 * 2 = 1§Safety and Overflow Handling
All arithmetic operations return Option<PreciseNumber>, returning None on:
- Overflow
- Underflow
- Division by zero
This ensures that your code can handle edge cases gracefully:
use nvana_fixed::PreciseNumber;
let a = PreciseNumber::new(5).unwrap();
let b = PreciseNumber::new(10).unwrap();
// Underflow returns None
assert!(a.checked_sub(&b).is_none());
// Division by zero returns None
let zero = PreciseNumber::zero();
assert!(a.checked_div(&zero).is_none());Re-exports§
pub use crate::precise_number::PreciseNumber;
Modules§
- precise_
number - Fixed-point decimal arithmetic implementation.