macro_rules! decl_decimal_int_methods {
(wide $Type:ident, $Storage:ty) => {
$crate::macros::int_methods::decl_decimal_int_methods!(@common $Type, $Storage);
impl<const SCALE: u32> $Type<SCALE> {
#[inline]
#[must_use]
pub fn div_floor(self, rhs: Self) -> Self {
let q = self.0 / rhs.0;
let r = self.0 % rhs.0;
let zero = <$Storage>::from_str_radix("0", 10)
.expect("wide decimal: invalid base-10 literal");
let one = <$Storage>::from_str_radix("1", 10)
.expect("wide decimal: invalid base-10 literal");
let raw = if r != zero && (r ^ rhs.0).is_negative() {
q - one
} else {
q
};
Self(raw * Self::multiplier())
}
#[inline]
#[must_use]
pub fn div_ceil(self, rhs: Self) -> Self {
let q = self.0 / rhs.0;
let r = self.0 % rhs.0;
let zero = <$Storage>::from_str_radix("0", 10)
.expect("wide decimal: invalid base-10 literal");
let one = <$Storage>::from_str_radix("1", 10)
.expect("wide decimal: invalid base-10 literal");
let raw = if r != zero && !(r ^ rhs.0).is_negative() {
q + one
} else {
q
};
Self(raw * Self::multiplier())
}
#[inline]
#[must_use]
pub fn is_zero(self) -> bool {
self == Self::ZERO
}
#[inline]
#[must_use]
pub fn is_normal(self) -> bool {
self != Self::ZERO
}
}
};
($Type:ident, $Storage:ty) => {
$crate::macros::int_methods::decl_decimal_int_methods!(@common $Type, $Storage);
impl<const SCALE: u32> $Type<SCALE> {
#[inline]
#[must_use]
pub fn div_floor(self, rhs: Self) -> Self {
let q = self.0 / rhs.0;
let r = self.0 % rhs.0;
let raw = if r != 0 && (r ^ rhs.0) < 0 { q - 1 } else { q };
Self(raw * Self::multiplier())
}
#[inline]
#[must_use]
pub fn div_ceil(self, rhs: Self) -> Self {
let q = self.0 / rhs.0;
let r = self.0 % rhs.0;
let raw = if r != 0 && (r ^ rhs.0) >= 0 { q + 1 } else { q };
Self(raw * Self::multiplier())
}
#[inline]
#[must_use]
pub const fn is_zero(self) -> bool {
self.0 == 0
}
#[inline]
#[must_use]
pub const fn is_normal(self) -> bool {
self.0 != 0
}
}
};
(@common $Type:ident, $Storage:ty) => {
impl<const SCALE: u32> $Type<SCALE> {
#[inline]
#[must_use]
pub fn div_euclid(self, rhs: Self) -> Self {
Self(self.0.div_euclid(rhs.0) * Self::multiplier())
}
#[inline]
#[must_use]
pub fn rem_euclid(self, rhs: Self) -> Self {
Self(self.0.rem_euclid(rhs.0))
}
#[inline]
#[must_use]
pub fn abs_diff(self, rhs: Self) -> Self {
Self(self.0.max(rhs.0) - self.0.min(rhs.0))
}
#[inline]
#[must_use]
pub fn midpoint(self, rhs: Self) -> Self {
Self((self.0 & rhs.0) + ((self.0 ^ rhs.0) >> 1u32))
}
#[inline]
#[must_use]
pub const fn is_nan(self) -> bool {
false
}
#[inline]
#[must_use]
pub const fn is_infinite(self) -> bool {
false
}
#[inline]
#[must_use]
pub const fn is_finite(self) -> bool {
true
}
#[inline]
#[must_use]
pub fn mul_add(self, a: Self, b: Self) -> Self {
self * a + b
}
}
};
}
pub(crate) use decl_decimal_int_methods;