use core::cmp::Ordering;
use core::hint::unreachable_unchecked;
#[derive(Copy, Clone, Debug, Default)]
#[non_exhaustive]
#[cfg_attr(no_re_export, allow(dead_code))]
#[allow(clippy::empty_docs)]
pub enum Rounding {
RoundDown,
RoundUp,
RoundTowardsZero,
RoundAwayFromZero,
RoundHalfDown,
RoundHalfUp,
RoundHalfTowardsZero,
#[default]
RoundHalfAwayFromZero,
RoundHalfToEven,
RoundHalfToOdd,
}
impl Rounding {
#[inline]
pub(crate) fn round_away_from_zero(
self,
is_negative: bool,
before: i8,
after: i8,
no_trailing_digits: bool,
) -> bool {
match self {
Rounding::RoundDown
| Rounding::RoundUp
| Rounding::RoundTowardsZero
| Rounding::RoundAwayFromZero => {
if after == 0 && no_trailing_digits {
false
} else {
match self {
Rounding::RoundDown => is_negative,
Rounding::RoundUp => !is_negative,
Rounding::RoundTowardsZero => false,
Rounding::RoundAwayFromZero => true,
_ => unsafe { unreachable_unchecked() },
}
}
}
Rounding::RoundHalfDown
| Rounding::RoundHalfUp
| Rounding::RoundHalfTowardsZero
| Rounding::RoundHalfAwayFromZero
| Rounding::RoundHalfToEven
| Rounding::RoundHalfToOdd => {
match after.cmp(&5).then_with(|| {
if no_trailing_digits {
Ordering::Equal
} else {
Ordering::Greater
}
}) {
Ordering::Less => false,
Ordering::Equal => match self {
Rounding::RoundHalfDown => is_negative,
Rounding::RoundHalfUp => !is_negative,
Rounding::RoundHalfTowardsZero => false,
Rounding::RoundHalfAwayFromZero => true,
Rounding::RoundHalfToEven => before & 1 != 0,
Rounding::RoundHalfToOdd => before & 1 == 0,
_ => unsafe { unreachable_unchecked() },
},
Ordering::Greater => true,
}
}
}
}
}