1#[macro_export]
2macro_rules! approx_eq {
3 ($typ:ty, $lhs:expr, $rhs:expr) => {
4 {
5 let m = <$typ as $crate::ApproxEq>::Margin::default();
6 <$typ as $crate::ApproxEq>::approx_eq($lhs, $rhs, m)
7 }
8 };
9 ($typ:ty, $lhs:expr, $rhs:expr $(, $set:ident = $val:expr)*) => {
10 {
11 use $crate::FloatMargin;
12 let m = <$typ as $crate::ApproxEq>::Margin::zero()$(.$set($val))*;
13 <$typ as $crate::ApproxEq>::approx_eq($lhs, $rhs, m)
14 }
15 };
16 ($typ:ty, $lhs:expr, $rhs:expr, $marg:expr) => {
17 {
18 <$typ as $crate::ApproxEq>::approx_eq($lhs, $rhs, $marg)
19 }
20 };
21}
22
23#[macro_export]
24macro_rules! assert_approx_eq {
25 ($typ:ty, $lhs:expr, $rhs:expr) => {
26 {
27 match (&$lhs, &$rhs) {
28 (left_val, right_val) => {
29 if !$crate::approx_eq!($typ, *left_val, *right_val) {
30 panic!(
31 r#"assertion failed: `(left approx_eq right)`
32 left: `{:?}`,
33 right: `{:?}`"#,
34 left_val, right_val,
35 )
36 }
37 }
38 }
39 }
40 };
41 ($typ:ty, $lhs:expr, $rhs:expr $(, $set:ident = $val:expr)*) => {
42 {
43 match (&$lhs, &$rhs) {
44 (left_val, right_val) => {
45 if !$crate::approx_eq!($typ, *left_val, *right_val $(, $set = $val)*) {
46 panic!(
47 r#"assertion failed: `(left approx_eq right)`
48 left: `{:?}`,
49 right: `{:?}`"#,
50 left_val, right_val,
51 )
52 }
53 }
54 }
55 }
56 };
57 ($typ:ty, $lhs:expr, $rhs:expr, $marg:expr) => {
58 {
59 match (&$lhs, &$rhs) {
60 (left_val, right_val) => {
61 if !$crate::approx_eq!($typ, *left_val, *right_val, $marg) {
62 panic!(
63 r#"assertion failed: `(left approx_eq right)`
64 left: `{:?}`,
65 right: `{:?}`"#,
66 left_val, right_val,
67 )
68 }
69 }
70 }
71 }
72 };
73}
74
75macro_rules! saturating_abs_i32 {
77 ($val:expr) => {
78 if $val.is_negative() {
79 match $val.checked_neg() {
80 Some(v) => v,
81 None => i32::MAX,
82 }
83 } else {
84 $val
85 }
86 };
87}
88macro_rules! saturating_abs_i64 {
89 ($val:expr) => {
90 if $val.is_negative() {
91 match $val.checked_neg() {
92 Some(v) => v,
93 None => i64::MAX,
94 }
95 } else {
96 $val
97 }
98 };
99}
100
101#[test]
102fn test_macro() {
103 let a: f32 = 0.15 + 0.15 + 0.15;
104 let b: f32 = 0.1 + 0.1 + 0.25;
105 assert!(approx_eq!(f32, a, b)); assert!(approx_eq!(f32, a, b, ulps = 2));
107 assert!(approx_eq!(f32, a, b, epsilon = 0.00000003));
108 assert!(approx_eq!(f32, a, b, epsilon = 0.00000003, ulps = 2));
109 assert!(approx_eq!(f32, a, b, (0.0, 2)));
110
111 assert_approx_eq!(f32, a, b); assert_approx_eq!(f32, a, b, ulps = 2);
113 assert_approx_eq!(f32, a, b, epsilon = 0.00000003);
114 assert_approx_eq!(f32, a, b, epsilon = 0.00000003, ulps = 2);
115 assert_approx_eq!(f32, a, b, (0.0, 2));
116}
117
118#[test]
119fn test_macro_2() {
120 assert!(approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64));
121 assert!(approx_eq!(
122 f64,
123 1000000_f64,
124 1000000.0000000003_f64,
125 ulps = 3
126 ));
127 assert!(approx_eq!(
128 f64,
129 1000000_f64,
130 1000000.0000000003_f64,
131 epsilon = 0.0000000004
132 ));
133 assert!(approx_eq!(
134 f64,
135 1000000_f64,
136 1000000.0000000003_f64,
137 (0.0000000004, 0)
138 ));
139 assert!(approx_eq!(
140 f64,
141 1000000_f64,
142 1000000.0000000003_f64,
143 (0.0, 3)
144 ));
145
146 assert_approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64);
147 assert_approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64, ulps = 3);
148 assert_approx_eq!(
149 f64,
150 1000000_f64,
151 1000000.0000000003_f64,
152 epsilon = 0.0000000004
153 );
154 assert_approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64, (0.0000000004, 0));
155 assert_approx_eq!(f64, 1000000_f64, 1000000.0000000003_f64, (0.0, 3));
156}
157
158#[test]
159fn test_macro_3() {
160 use crate::F32Margin;
161
162 let a: f32 = 0.15 + 0.15 + 0.15;
163 let b: f32 = 0.1 + 0.1 + 0.25;
164 assert!(approx_eq!(
165 f32,
166 a,
167 b,
168 F32Margin {
169 epsilon: 0.0,
170 ulps: 2
171 }
172 ));
173 assert!(approx_eq!(f32, a, b, F32Margin::default()));
174
175 assert_approx_eq!(
176 f32,
177 a,
178 b,
179 F32Margin {
180 epsilon: 0.0,
181 ulps: 2
182 }
183 );
184 assert_approx_eq!(f32, a, b, F32Margin::default());
185}
186
187#[test]
188#[should_panic]
189fn test_macro_4() {
190 let a: f32 = 0.15 + 0.15 + 0.15;
191 let b: f32 = 1.0;
192
193 assert_approx_eq!(f32, a, b);
194}
195
196#[test]
197#[should_panic]
198fn test_macro_5() {
199 let a: f32 = 0.15 + 0.15 + 0.15;
200 let b: f32 = 1.0;
201
202 assert_approx_eq!(f32, a, b, ulps = 2);
203}
204
205#[test]
206#[should_panic]
207fn test_macro_6() {
208 let a: f32 = 0.15 + 0.15 + 0.15;
209 let b: f32 = 1.0;
210
211 assert_approx_eq!(f32, a, b, epsilon = 0.00000003);
212}
213
214#[test]
215#[should_panic]
216fn test_macro_7() {
217 let a: f32 = 0.15 + 0.15 + 0.15;
218 let b: f32 = 1.0;
219
220 assert_approx_eq!(f32, a, b, epsilon = 0.00000003, ulps = 2);
221}
222
223#[test]
224#[should_panic]
225fn test_macro_8() {
226 let a: f32 = 0.15 + 0.15 + 0.15;
227 let b: f32 = 1.0;
228
229 assert_approx_eq!(f32, a, b, (0.0, 2));
230}