radix_common/math/
rounding_mode.rs1use core::cmp::Ordering;
2use sbor::Sbor;
3
4#[cfg_attr(
8 feature = "fuzzing",
9 derive(::arbitrary::Arbitrary, ::serde::Serialize, ::serde::Deserialize)
10)]
11#[derive(Debug, Clone, Copy, PartialEq, Eq, Sbor)]
12pub enum RoundingMode {
13 ToPositiveInfinity,
15 ToNegativeInfinity,
17 ToZero,
19 AwayFromZero,
21
22 ToNearestMidpointTowardZero,
24 ToNearestMidpointAwayFromZero,
26 ToNearestMidpointToEven,
28}
29
30#[allow(clippy::enum_variant_names)]
32pub(crate) enum ResolvedRoundingStrategy {
33 RoundUp,
34 RoundDown,
35 RoundToEven,
36}
37
38impl ResolvedRoundingStrategy {
39 pub fn from_mode(
40 mode: RoundingMode,
41 is_positive: bool,
42 compare_to_midpoint: impl FnOnce() -> Ordering,
43 ) -> Self {
44 match mode {
45 RoundingMode::ToPositiveInfinity => ResolvedRoundingStrategy::RoundUp,
46 RoundingMode::ToNegativeInfinity => ResolvedRoundingStrategy::RoundDown,
47 RoundingMode::ToZero => ResolvedRoundingStrategy::towards_zero(is_positive),
48 RoundingMode::AwayFromZero => ResolvedRoundingStrategy::away_from_zero(is_positive),
49 RoundingMode::ToNearestMidpointTowardZero => Self::from_midpoint_ordering(
50 compare_to_midpoint(),
51 ResolvedRoundingStrategy::towards_zero(is_positive),
52 ),
53 RoundingMode::ToNearestMidpointAwayFromZero => Self::from_midpoint_ordering(
54 compare_to_midpoint(),
55 ResolvedRoundingStrategy::away_from_zero(is_positive),
56 ),
57 RoundingMode::ToNearestMidpointToEven => Self::from_midpoint_ordering(
58 compare_to_midpoint(),
59 ResolvedRoundingStrategy::RoundToEven,
60 ),
61 }
62 }
63
64 fn from_midpoint_ordering(ordering: Ordering, equal_strategy: Self) -> Self {
65 match ordering {
66 Ordering::Less => Self::RoundDown,
67 Ordering::Equal => equal_strategy,
68 Ordering::Greater => Self::RoundUp,
69 }
70 }
71
72 fn towards_zero(is_positive: bool) -> Self {
73 if is_positive {
74 Self::RoundDown
75 } else {
76 Self::RoundUp
77 }
78 }
79
80 fn away_from_zero(is_positive: bool) -> Self {
81 if is_positive {
82 Self::RoundUp
83 } else {
84 Self::RoundDown
85 }
86 }
87}