pub struct Decimal64 { /* private fields */ }Expand description
A fixed-precision decimal stored as a 64-bit integer with embedded scale.
§Storage Design
Unlike designs where scale is external, Decimal64 packs both value and scale
into a single 64-bit integer:
Byte: [0] [1] [2] [3] [4] [5] [6] [7]
Scale |<---------------- 56-bit signed value ---------------->|- Scale (byte 0): 0-18 for normal values, special markers for Infinity/NaN
- Value (bytes 1-7): 56-bit signed integer representing
actual_value * 10^scale
§Trade-offs
| Aspect | Decimal64 (embedded scale) | External scale design |
|---|---|---|
| Precision | 16 digits | 18 digits |
| Self-contained | Yes (scale included) | No (need metadata) |
| API simplicity | to_string() works | Need to_string_with_scale(s) |
| Columnar storage | Scale repeated per value | Scale in column metadata |
§Special Values
Special values are encoded using reserved scale bytes:
- Scale = 253: -Infinity
- Scale = 254: +Infinity
- Scale = 255: NaN
§Ordering
Within the same scale, values are ordered correctly. Across different scales,
ordering requires conversion to a common scale or use of cmp().
Implementations§
Source§impl Decimal64
impl Decimal64
Sourcepub fn new(s: &str, scale: u8) -> Result<Self, DecimalError>
pub fn new(s: &str, scale: u8) -> Result<Self, DecimalError>
Creates a Decimal64 from a string with automatic scale detection.
The scale is determined from the number of digits after the decimal point.
§Examples
use decimal_bytes::Decimal64;
let d = Decimal64::new("123.45", 2).unwrap();
assert_eq!(d.to_string(), "123.45");
assert_eq!(d.scale(), 2);
let d = Decimal64::new("100", 0).unwrap();
assert_eq!(d.to_string(), "100");
assert_eq!(d.scale(), 0);Sourcepub fn with_precision_scale(
s: &str,
precision: Option<u32>,
scale: Option<i32>,
) -> Result<Self, DecimalError>
pub fn with_precision_scale( s: &str, precision: Option<u32>, scale: Option<i32>, ) -> Result<Self, DecimalError>
Creates a Decimal64 with precision and scale constraints (PostgreSQL NUMERIC semantics).
precision: Maximum total significant digits (1-16, or None for no limit)scale: Digits after decimal point (0-18, or negative for rounding left of decimal)
§Examples
use decimal_bytes::Decimal64;
// NUMERIC(5, 2) - up to 5 digits total, 2 after decimal
let d = Decimal64::with_precision_scale("123.456", Some(5), Some(2)).unwrap();
assert_eq!(d.to_string(), "123.46");
// NUMERIC(2, -3) - rounds to nearest 1000
let d = Decimal64::with_precision_scale("12345", Some(2), Some(-3)).unwrap();
assert_eq!(d.to_string(), "12000");Sourcepub fn from_parts(value: i64, scale: u8) -> Result<Self, DecimalError>
pub fn from_parts(value: i64, scale: u8) -> Result<Self, DecimalError>
Sourcepub const fn from_raw(packed: i64) -> Self
pub const fn from_raw(packed: i64) -> Self
Creates a Decimal64 from a raw packed i64 (for deserialization).
Sourcepub const fn neg_infinity() -> Self
pub const fn neg_infinity() -> Self
Creates negative infinity.
Sourcepub const fn nan() -> Self
pub const fn nan() -> Self
Creates NaN (Not a Number).
Follows PostgreSQL semantics: NaN == NaN is true.
Sourcepub fn scale(&self) -> u8
pub fn scale(&self) -> u8
Returns the scale (digits after decimal point).
Returns 0 for special values (NaN, Infinity).
Sourcepub fn is_negative(&self) -> bool
pub fn is_negative(&self) -> bool
Returns true if this value is negative (excluding -Infinity).
Sourcepub fn is_positive(&self) -> bool
pub fn is_positive(&self) -> bool
Returns true if this value is positive (excluding +Infinity and NaN).
Sourcepub fn is_pos_infinity(&self) -> bool
pub fn is_pos_infinity(&self) -> bool
Returns true if this value is positive infinity.
Sourcepub fn is_neg_infinity(&self) -> bool
pub fn is_neg_infinity(&self) -> bool
Returns true if this value is negative infinity.
Sourcepub fn is_infinity(&self) -> bool
pub fn is_infinity(&self) -> bool
Returns true if this value is positive or negative infinity.
Sourcepub fn is_special(&self) -> bool
pub fn is_special(&self) -> bool
Returns true if this is a special value (Infinity or NaN).
Sourcepub fn to_be_bytes(&self) -> [u8; 8]
pub fn to_be_bytes(&self) -> [u8; 8]
Returns the 8-byte big-endian representation.
Sourcepub fn from_be_bytes(bytes: [u8; 8]) -> Self
pub fn from_be_bytes(bytes: [u8; 8]) -> Self
Creates a Decimal64 from big-endian bytes.
Sourcepub fn to_decimal(&self) -> Decimal
pub fn to_decimal(&self) -> Decimal
Converts to the variable-length Decimal type.
Sourcepub fn from_decimal(decimal: &Decimal, scale: u8) -> Result<Self, DecimalError>
pub fn from_decimal(decimal: &Decimal, scale: u8) -> Result<Self, DecimalError>
Creates a Decimal64 from a Decimal with the specified scale.