1use core::ops::{BitOr, BitOrAssign};
5
6#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
11#[repr(u8)]
12pub enum RoundMode {
13 #[default]
14 NearEven = 0,
15 ToZero = 1,
16 Down = 2,
17 Up = 3,
18 NearMaxMag = 4,
19 Odd = 5,
20}
21
22#[derive(Clone, Copy, Debug, PartialEq, Eq)]
27pub struct ExcFlags(pub u8);
28
29impl ExcFlags {
30 pub const NONE: Self = Self(0);
31 pub const INVALID: Self = Self(1);
32 pub const DIVBYZERO: Self = Self(2);
33 pub const OVERFLOW: Self = Self(4);
34 pub const UNDERFLOW: Self = Self(8);
35 pub const INEXACT: Self = Self(16);
36
37 #[inline]
38 pub fn is_empty(self) -> bool {
39 self.0 == 0
40 }
41 #[inline]
42 pub fn contains(self, other: Self) -> bool {
43 self.0 & other.0 != 0
44 }
45}
46
47impl BitOr for ExcFlags {
48 type Output = Self;
49 #[inline]
50 fn bitor(self, rhs: Self) -> Self {
51 Self(self.0 | rhs.0)
52 }
53}
54
55impl BitOrAssign for ExcFlags {
56 #[inline]
57 fn bitor_assign(&mut self, rhs: Self) {
58 self.0 |= rhs.0;
59 }
60}
61
62#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
67pub enum Tininess {
68 BeforeRounding,
69 #[default]
70 AfterRounding,
71}
72
73#[derive(Clone, Copy, Debug)]
78pub struct FloatEnv {
79 round_mode: RoundMode,
80 flags: ExcFlags,
81 tininess: Tininess,
82 default_nan: bool,
83}
84
85impl FloatEnv {
86 pub fn new(rm: RoundMode) -> Self {
87 Self {
88 round_mode: rm,
89 flags: ExcFlags::NONE,
90 tininess: Tininess::AfterRounding,
91 default_nan: false,
92 }
93 }
94
95 #[inline]
96 pub fn round_mode(&self) -> RoundMode {
97 self.round_mode
98 }
99 #[inline]
100 pub fn set_round_mode(&mut self, rm: RoundMode) {
101 self.round_mode = rm;
102 }
103
104 #[inline]
105 pub fn flags(&self) -> ExcFlags {
106 self.flags
107 }
108 #[inline]
109 pub fn set_flags(&mut self, f: ExcFlags) {
110 self.flags = f;
111 }
112 #[inline]
113 pub fn raise(&mut self, f: ExcFlags) {
114 self.flags |= f;
115 }
116 #[inline]
117 pub fn clear_flags(&mut self) {
118 self.flags = ExcFlags::NONE;
119 }
120
121 #[inline]
122 pub fn tininess(&self) -> Tininess {
123 self.tininess
124 }
125 #[inline]
126 pub fn set_tininess(&mut self, t: Tininess) {
127 self.tininess = t;
128 }
129
130 #[inline]
131 pub fn default_nan(&self) -> bool {
132 self.default_nan
133 }
134 #[inline]
135 pub fn set_default_nan(&mut self, v: bool) {
136 self.default_nan = v;
137 }
138}
139
140impl Default for FloatEnv {
141 fn default() -> Self {
142 Self::new(RoundMode::NearEven)
143 }
144}