radix_common/math/
rounding_mode.rs1#[cfg(feature = "fuzzing")]
2use arbitrary::Arbitrary;
3use core::cmp::Ordering;
4use sbor::Sbor;
5#[cfg(feature = "fuzzing")]
6use serde::{Deserialize, Serialize};
7
8#[cfg_attr(feature = "fuzzing", derive(Arbitrary, Serialize, Deserialize))]
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Sbor)]
13pub enum RoundingMode {
14 ToPositiveInfinity,
16 ToNegativeInfinity,
18 ToZero,
20 AwayFromZero,
22
23 ToNearestMidpointTowardZero,
25 ToNearestMidpointAwayFromZero,
27 ToNearestMidpointToEven,
29}
30
31pub(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}