Expand description
§decimal-bytes
Arbitrary precision decimals with lexicographically sortable byte encoding.
This crate provides three decimal types optimized for database storage:
Decimal: Variable-length arbitrary precision (up to 131,072 digits)Decimal64: Fixed 8-byte representation with embedded scale (precision ≤ 16 digits)Decimal64NoScale: Fixed 8-byte representation with external scale (precision ≤ 18 digits)
All types support PostgreSQL special values (NaN, ±Infinity) with correct sort ordering.
§When to Use Which
| Type | Precision | Scale | Storage | Best For |
|---|---|---|---|---|
Decimal64NoScale | ≤ 18 digits | External | 8 bytes | Columnar storage, aggregates |
Decimal64 | ≤ 16 digits | Embedded | 8 bytes | Self-contained values |
Decimal | Unlimited | Unlimited | Variable | Scientific, very large numbers |
§Decimal64NoScale (Recommended for Columnar Storage)
use decimal_bytes::Decimal64NoScale;
// Scale is provided externally (e.g., from schema metadata)
let scale = 2;
let a = Decimal64NoScale::new("100.50", scale).unwrap();
let b = Decimal64NoScale::new("200.25", scale).unwrap();
// Aggregates work correctly - just sum the raw i64 values!
let sum = a.value() + b.value(); // 30075
let result = Decimal64NoScale::from_raw(sum);
assert_eq!(result.to_string_with_scale(scale), "300.75");§Decimal64 Example
use decimal_bytes::Decimal64;
// Create with embedded scale
let price = Decimal64::new("99.99", 2).unwrap();
assert_eq!(price.to_string(), "99.99");
assert_eq!(price.scale(), 2); // Scale is embedded!
// With precision and scale (PostgreSQL NUMERIC semantics)
let d = Decimal64::with_precision_scale("123.456", Some(5), Some(2)).unwrap();
assert_eq!(d.to_string(), "123.46"); // Rounded
// Parse with automatic scale detection
let d: Decimal64 = "123.456".parse().unwrap();
assert_eq!(d.scale(), 3);
// Special values
let inf = Decimal64::infinity();
let nan = Decimal64::nan();
assert!(price < inf);
assert!(inf < nan);§Decimal Example (Arbitrary Precision)
use decimal_bytes::Decimal;
use std::str::FromStr;
// Create decimals
let a = Decimal::from_str("123.456").unwrap();
let b = Decimal::from_str("123.457").unwrap();
// Byte comparison matches numerical comparison
assert!(a.as_bytes() < b.as_bytes());
assert!(a < b);
// Special values (PostgreSQL compatible)
let inf = Decimal::infinity();
let nan = Decimal::nan();
assert!(a < inf);
assert!(inf < nan);§Sort Order
The lexicographic byte order matches PostgreSQL NUMERIC:
-Infinity < negative numbers < zero < positive numbers < +Infinity < NaNBoth Decimal and Decimal64 support this sort order including special values.
§Special Value Semantics (PostgreSQL vs IEEE 754)
The Decimal type follows PostgreSQL semantics for special values:
| Behavior | PostgreSQL / decimal-bytes | IEEE 754 float |
|---|---|---|
NaN == NaN | true | false |
NaN ordering | Greatest value (> Infinity) | Unordered |
Infinity == Infinity | true | true |
use decimal_bytes::Decimal;
let nan1 = Decimal::nan();
let nan2 = Decimal::nan();
let inf = Decimal::infinity();
// NaN equals itself (PostgreSQL behavior, unlike IEEE 754)
assert_eq!(nan1, nan2);
// NaN is greater than everything, including Infinity
assert!(nan1 > inf);This makes Decimal suitable for use in indexes, sorting, and deduplication
where consistent ordering and equality semantics are required.
Structs§
- Decimal
- An arbitrary precision decimal number stored as sortable bytes.
- Decimal64
- A fixed-precision decimal stored as a 64-bit integer with embedded scale.
- Decimal64
NoScale - A fixed-precision decimal stored as a raw 64-bit integer.
Enums§
- Decimal
Error - Errors that can occur during decimal encoding/decoding.
- Special
Value - Special decimal values (IEEE 754 / PostgreSQL compatible)
Constants§
- MAX_
DECIMA L64_ NO_ SCALE_ PRECISION - Maximum precision that fits in signed i64 (18 digits). i64::MAX = 9,223,372,036,854,775,807 ≈ 9.2 × 10^18
- MAX_
DECIMA L64_ NO_ SCALE_ SCALE - Maximum scale supported.
- MAX_
DECIMA L64_ PRECISION - Maximum precision that fits in 56-bit value (16 digits).
- MAX_
DECIMA L64_ SCALE - Maximum scale supported (0-18).