pub struct Dec(/* private fields */);Expand description
A decimal carrying a fixed Dec::SCALE decimal places, backed by an
i128 holding the value scaled by 10^SCALE.
Arithmetic is exact between Dec::MIN and Dec::MAX. Anything that
leaves that range becomes Dec::NAN and stays NaN through every later
operation, so the fault reaches the boundary where Dec::is_finite is
checked rather than being clamped to a plausible number or raised as a
panic on a hot path.
The ordering is total: NaN equals itself and sorts below Dec::MIN,
which keeps Eq, Ord and Hash derivable and so keeps Dec usable as a
BTreeMap or HashMap key. See the design notes for why.
use troy::{Dec, dec};
assert_eq!(dec!(2.5) + dec!(0.25), dec!(2.75));
assert!((Dec::MAX + Dec::ONE).is_nan());Implementations§
Source§impl Dec
impl Dec
Sourcepub const MIN: Self
pub const MIN: Self
The smallest finite value, -Dec::MAX. The finite range is symmetric,
so negation and Dec::abs are total and exact on it.
Sourcepub const NAN: Self
pub const NAN: Self
The not-a-number state. Every operation that leaves the finite range
returns it, and every operation given it returns it, so an invalid
result carries its own invalidity to wherever it is finally checked
with Dec::is_finite.
Unlike an IEEE NaN this one is ordered and reflexive: it equals itself
and sorts below Dec::MIN, which is what keeps Eq and Ord
available. It therefore wins any min reduction and sorts to the front
of a collection.
use troy::Dec;
assert_eq!(Dec::NAN, Dec::NAN);
assert!(Dec::NAN < Dec::MIN);
assert!(!Dec::NAN.is_finite());Sourcepub const fn from_raw(raw: i128) -> Self
pub const fn from_raw(raw: i128) -> Self
Wrap a raw scaled integer. Total: i128::MIN is Dec::NAN, so every
raw round trips through Dec::into_raw.
Sourcepub const fn is_nan(self) -> bool
pub const fn is_nan(self) -> bool
Whether this is Dec::NAN, the state every overflow collapses to.
Sourcepub const fn is_finite(self) -> bool
pub const fn is_finite(self) -> bool
Whether this is an ordinary number, the check to make where a value leaves the system.
use troy::{Dec, dec};
assert!(dec!(1.5).is_finite());
assert!(Dec::MAX.is_finite());
assert!(!(Dec::MAX * Dec::MAX).is_finite());Sourcepub const fn into_raw(self) -> i128
pub const fn into_raw(self) -> i128
The underlying scaled integer, the inverse of Dec::from_raw.
Sourcepub const fn from_int(value: i64) -> Self
pub const fn from_int(value: i64) -> Self
An exact whole number. Every i64 fits the finite range.
Sourcepub const fn from_u64(value: u64) -> Self
pub const fn from_u64(value: u64) -> Self
An exact whole number. Every u64 fits the finite range.
Sourcepub const fn parse_const(value: &str) -> Option<Self>
pub const fn parse_const(value: &str) -> Option<Self>
Parse in a const context, None on malformed or out-of-range text.
The dec! macro wraps this.
Sourcepub const fn is_sign_negative(self) -> bool
pub const fn is_sign_negative(self) -> bool
Whether this is a finite value below zero. Dec::NAN is neither
negative nor positive, so this is not a finiteness test.
Sourcepub const fn is_sign_positive(self) -> bool
pub const fn is_sign_positive(self) -> bool
Whether this is a value above zero. Dec::NAN is not.
Sourcepub const fn abs(self) -> Self
pub const fn abs(self) -> Self
The magnitude, exact for every finite value because the range is
symmetric. Dec::NAN stays NaN.
Sourcepub const fn signum(self) -> Self
pub const fn signum(self) -> Self
Dec::ONE, Dec::NEG_ONE or Dec::ZERO by sign. Dec::NAN
stays NaN.
Sourcepub fn to_f64(self) -> f64
pub fn to_f64(self) -> f64
Convert to f64, rounding to the nearest representable double.
Dec::NAN becomes f64::NAN.
Sourcepub fn from_f64(value: f64) -> Option<Self>
pub fn from_f64(value: f64) -> Option<Self>
Convert from f64, or None when the value is not finite or does not
fit the finite range. This never yields Dec::NAN: a conversion
reports failure directly, since there is no earlier computation for a
NaN to have propagated from.
Sourcepub const fn trunc(self) -> Self
pub const fn trunc(self) -> Self
The whole part, rounding towards zero. Always finite for a finite
input; Dec::NAN stays NaN.
Sourcepub const fn checked_add(self, rhs: Self) -> Option<Self>
pub const fn checked_add(self, rhs: Self) -> Option<Self>
The sum, or None if it leaves the finite range or either side is
Dec::NAN. Use this where an overflow should be handled on the spot
rather than propagated.
Sourcepub const fn checked_sub(self, rhs: Self) -> Option<Self>
pub const fn checked_sub(self, rhs: Self) -> Option<Self>
The difference, or None if it leaves the finite range or either side
is Dec::NAN.
Sourcepub fn checked_mul(self, rhs: Self) -> Option<Self>
pub fn checked_mul(self, rhs: Self) -> Option<Self>
The product, or None if it leaves the finite range or either side is
Dec::NAN. Exact, with the excess below Dec::SCALE rounded half
away from zero.
Sourcepub fn checked_div(self, rhs: Self) -> Option<Self>
pub fn checked_div(self, rhs: Self) -> Option<Self>
The quotient, or None on division by zero, if it leaves the finite
range, or if either side is Dec::NAN.
Sourcepub fn saturating_div(self, rhs: Self) -> Self
pub fn saturating_div(self, rhs: Self) -> Self
Sourcepub fn saturating_mul(self, rhs: Self) -> Self
pub fn saturating_mul(self, rhs: Self) -> Self
Sourcepub const fn saturating_add(self, rhs: Self) -> Self
pub const fn saturating_add(self, rhs: Self) -> Self
Sourcepub const fn saturating_sub(self, rhs: Self) -> Self
pub const fn saturating_sub(self, rhs: Self) -> Self
Source§impl Dec
impl Dec
Sourcepub fn from_decimal(value: Decimal) -> Option<Self>
pub fn from_decimal(value: Decimal) -> Option<Self>
Rescale a Decimal, exact unless it carries more than Dec::SCALE
decimal places, where the excess rounds half away from zero.
Sourcepub fn to_decimal(self) -> Option<Decimal>
pub fn to_decimal(self) -> Option<Decimal>
Widen to a Decimal at Dec::SCALE decimal places, or None when the
value needs more than the 96 bits a Decimal mantissa holds.
Source§impl Dec
impl Dec
Sourcepub fn from_f64_round(value: f64, dp: u32) -> Option<Self>
pub fn from_f64_round(value: f64, dp: u32) -> Option<Self>
Dec::from_f64 followed by Dec::round_dp, which is how a float
carrying binary representation error is best pinned to a known scale.
Sourcepub const fn round_dp(self, dp: u32) -> Self
pub const fn round_dp(self, dp: u32) -> Self
Round to dp decimal places, halves away from zero. A no-op once dp
reaches Dec::SCALE. Returns Dec::NAN when the rounded value
leaves the finite range, as it does for Dec::MIN at dp 0, and
when the input is already NaN.
use troy::{Dec, dec};
assert_eq!(dec!(2.5).round_dp(0), dec!(3));
assert_eq!(dec!(-2.5).round_dp(0), dec!(-3));
assert!(Dec::MAX.round_dp(0).is_nan());Sourcepub const fn round_to_step(self, step: Self) -> Self
pub const fn round_to_step(self, step: Self) -> Self
Round to the nearest multiple of step, halves away from zero. A
non-positive step is a no-op. Returns Dec::NAN when the result
leaves the finite range, and when either side is already NaN.
use troy::dec;
assert_eq!(dec!(104_237.28).round_to_step(dec!(0.25)), dec!(104_237.25));Trait Implementations§
Source§impl Add for Dec
The sum, or Dec::NAN on overflow or from a NaN operand. See
Dec::checked_add and Dec::saturating_add to handle it on the spot.
impl Add for Dec
The sum, or Dec::NAN on overflow or from a NaN operand. See
Dec::checked_add and Dec::saturating_add to handle it on the spot.
Source§impl AddAssign for Dec
impl AddAssign for Dec
Source§fn add_assign(&mut self, rhs: Self)
fn add_assign(&mut self, rhs: Self)
+= operation. Read moreimpl Copy for Dec
Source§impl<'de> Deserialize<'de> for Dec
impl<'de> Deserialize<'de> for Dec
Source§fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>
fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error>
Source§impl Div for Dec
The quotient, or Dec::NAN on division by zero, on overflow, or from a
NaN operand.
impl Div for Dec
The quotient, or Dec::NAN on division by zero, on overflow, or from a
NaN operand.
There is no infinity in the type, so dividing by zero has no value to
return; it is the same fault as an overflow and collapses to the same NaN,
which then carries to wherever the result is examined rather than panicking
on a hot path. The quotient is exact at Dec::SCALE places, with a tie
rounding half away from zero. Dec::checked_div reports the fault,
Dec::saturating_div clamps an overflow.
Source§impl DivAssign for Dec
impl DivAssign for Dec
Source§fn div_assign(&mut self, rhs: Self)
fn div_assign(&mut self, rhs: Self)
/= operation. Read moreimpl Eq for Dec
Source§impl Mul for Dec
The product, or Dec::NAN on overflow or from a NaN operand.
impl Mul for Dec
The product, or Dec::NAN on overflow or from a NaN operand.
The finite range is +/-1.7e20 and no price, size or notional lives near it,
so an overflow here is a bug rather than a number: bad input, or an
accumulation that ran away. Saturating would answer it with a plausible
looking figure that survives every downstream check, so the operators
return NaN instead and carry the fault to wherever the result is finally
examined. Dec::checked_mul reports it, Dec::saturating_mul clamps
it, for callers who would rather decide on the spot.
Source§impl MulAssign for Dec
impl MulAssign for Dec
Source§fn mul_assign(&mut self, rhs: Self)
fn mul_assign(&mut self, rhs: Self)
*= operation. Read moreSource§impl Neg for Dec
Negation, which is exact and total: the finite range is symmetric, so every
value has a negation, and the NaN pattern is its own.
impl Neg for Dec
Negation, which is exact and total: the finite range is symmetric, so every value has a negation, and the NaN pattern is its own.
Source§impl Ord for Dec
impl Ord for Dec
1.21.0 (const: unstable) · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
1.21.0 (const: unstable) · Source§fn min(self, other: Self) -> Selfwhere
Self: Sized,
fn min(self, other: Self) -> Selfwhere
Self: Sized,
Source§impl PartialOrd for Dec
impl PartialOrd for Dec
impl StructuralPartialEq for Dec
Source§impl Sub for Dec
The difference, or Dec::NAN on overflow or from a NaN operand. See
Dec::checked_sub and Dec::saturating_sub to handle it on the spot.
impl Sub for Dec
The difference, or Dec::NAN on overflow or from a NaN operand. See
Dec::checked_sub and Dec::saturating_sub to handle it on the spot.
Source§impl SubAssign for Dec
impl SubAssign for Dec
Source§fn sub_assign(&mut self, rhs: Self)
fn sub_assign(&mut self, rhs: Self)
-= operation. Read more