1use crate::interval::*;
2use std::mem::transmute;
3
4impl Interval {
5 pub(crate) fn classify(self) -> IntervalClass {
6
7 let inf_ge_zero = (-self.inf >= 0.0) as u8;
9 let sup_ge_zero = (self.sup >= 0.0) as u8;
10 let ge_zero = sup_ge_zero << 1 | inf_ge_zero;
11
12 let inf_le_zero = (-self.inf <= 0.0) as u8;
14 let sup_le_zero = (self.sup <= 0.0) as u8;
15 let le_zero = sup_le_zero << 1 | inf_le_zero;
16
17 unsafe { transmute((le_zero << 2) | ge_zero) }
18 }
19
20 pub(crate) fn classify2(self, rhs: Self) -> IntervalClass2 {
21 unsafe { transmute(((self.classify() as u8) << 4) | rhs.classify() as u8) }
22 }
23}
24
25#[derive(Clone, Copy, Debug, Eq, PartialEq)]
41#[repr(u8)]
42pub(crate) enum IntervalClass {
43 E = 0b0000, M = 0b0011, N0 = 0b1011, N1 = 0b1001, P0 = 0b0111, P1 = 0b0110, Z = 0b1111, }
52
53macro_rules! discr {
54 ($x:ident, $y:ident) => {
55 ((IntervalClass::$x as u8) << 4) | IntervalClass::$y as u8
56 };
57}
58
59#[allow(dead_code)]
60#[allow(non_camel_case_types)] #[derive(Clone, Copy, Debug, Eq, PartialEq)]
62#[repr(u8)]
63pub(crate) enum IntervalClass2 {
64 E_E = discr!(E, E),
65 E_M = discr!(E, M),
66 E_N0 = discr!(E, N0),
67 E_N1 = discr!(E, N1),
68 E_P0 = discr!(E, P0),
69 E_P1 = discr!(E, P1),
70 E_Z = discr!(E, Z),
71
72 M_E = discr!(M, E),
73 M_M = discr!(M, M),
74 M_N0 = discr!(M, N0),
75 M_N1 = discr!(M, N1),
76 M_P0 = discr!(M, P0),
77 M_P1 = discr!(M, P1),
78 M_Z = discr!(M, Z),
79
80 N0_E = discr!(N0, E),
81 N0_M = discr!(N0, M),
82 N0_N0 = discr!(N0, N0),
83 N0_N1 = discr!(N0, N1),
84 N0_P0 = discr!(N0, P0),
85 N0_P1 = discr!(N0, P1),
86 N0_Z = discr!(N0, Z),
87
88 N1_E = discr!(N1, E),
89 N1_M = discr!(N1, M),
90 N1_N0 = discr!(N1, N0),
91 N1_N1 = discr!(N1, N1),
92 N1_P0 = discr!(N1, P0),
93 N1_P1 = discr!(N1, P1),
94 N1_Z = discr!(N1, Z),
95
96 P0_E = discr!(P0, E),
97 P0_M = discr!(P0, M),
98 P0_N0 = discr!(P0, N0),
99 P0_N1 = discr!(P0, N1),
100 P0_P0 = discr!(P0, P0),
101 P0_P1 = discr!(P0, P1),
102 P0_Z = discr!(P0, Z),
103
104 P1_E = discr!(P1, E),
105 P1_M = discr!(P1, M),
106 P1_N0 = discr!(P1, N0),
107 P1_N1 = discr!(P1, N1),
108 P1_P0 = discr!(P1, P0),
109 P1_P1 = discr!(P1, P1),
110 P1_Z = discr!(P1, Z),
111
112 Z_E = discr!(Z, E),
113 Z_M = discr!(Z, M),
114 Z_N0 = discr!(Z, N0),
115 Z_N1 = discr!(Z, N1),
116 Z_P0 = discr!(Z, P0),
117 Z_P1 = discr!(Z, P1),
118 Z_Z = discr!(Z, Z),
119}
120
121
122#[cfg(test)]
123mod tests {
124 use super::*;
125 use crate::*;
126 use Interval as I;
127
128 #[test]
129 fn classify() {
130 use IntervalClass::*;
131 assert_eq!(I::EMPTY.classify(), E);
132 assert_eq!(I::ENTIRE.classify(), M);
133 assert_eq!(const_interval!(-1.0, 1.0).classify(), M);
134 assert_eq!(const_interval!(-1.0, 0.0).classify(), N0);
135 assert_eq!(const_interval!(-1.0, -1.0).classify(), N1);
136 assert_eq!(const_interval!(0.0, 1.0).classify(), P0);
137 assert_eq!(const_interval!(1.0, 1.0).classify(), P1);
138 assert_eq!(I::zero().classify(), Z);
139 }
140}