1#[cfg(f16_enabled)]
6#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
7pub fn fminf16(x: f16, y: f16) -> f16 {
8 super::generic::fmin(x, y)
9}
10
11#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
16pub fn fminf(x: f32, y: f32) -> f32 {
17 super::generic::fmin(x, y)
18}
19
20#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
25pub fn fmin(x: f64, y: f64) -> f64 {
26 super::generic::fmin(x, y)
27}
28
29#[cfg(f128_enabled)]
34#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
35pub fn fminf128(x: f128, y: f128) -> f128 {
36 super::generic::fmin(x, y)
37}
38
39#[cfg(f16_enabled)]
44#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
45pub fn fmaxf16(x: f16, y: f16) -> f16 {
46 super::generic::fmax(x, y)
47}
48
49#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
54pub fn fmaxf(x: f32, y: f32) -> f32 {
55 super::generic::fmax(x, y)
56}
57
58#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
63pub fn fmax(x: f64, y: f64) -> f64 {
64 super::generic::fmax(x, y)
65}
66
67#[cfg(f128_enabled)]
72#[cfg_attr(all(test, assert_no_panic), no_panic::no_panic)]
73pub fn fmaxf128(x: f128, y: f128) -> f128 {
74 super::generic::fmax(x, y)
75}
76
77#[cfg(test)]
78mod tests {
79 use super::*;
80 use crate::support::{Float, Hexf};
81
82 fn fmin_spec_test<F: Float>(f: impl Fn(F, F) -> F) {
83 let cases = [
84 (F::ZERO, F::ZERO, F::ZERO),
85 (F::ZERO, F::ONE, F::ZERO),
86 (F::ZERO, F::NEG_ONE, F::NEG_ONE),
87 (F::ZERO, F::INFINITY, F::ZERO),
88 (F::ZERO, F::NEG_INFINITY, F::NEG_INFINITY),
89 (F::ZERO, F::NAN, F::ZERO),
90 (F::ZERO, F::NEG_NAN, F::ZERO),
91 (F::NEG_ZERO, F::NEG_ZERO, F::NEG_ZERO),
92 (F::NEG_ZERO, F::ONE, F::NEG_ZERO),
93 (F::NEG_ZERO, F::NEG_ONE, F::NEG_ONE),
94 (F::NEG_ZERO, F::INFINITY, F::NEG_ZERO),
95 (F::NEG_ZERO, F::NEG_INFINITY, F::NEG_INFINITY),
96 (F::NEG_ZERO, F::NAN, F::NEG_ZERO),
97 (F::NEG_ZERO, F::NEG_NAN, F::NEG_ZERO),
98 (F::ONE, F::ZERO, F::ZERO),
99 (F::ONE, F::NEG_ZERO, F::NEG_ZERO),
100 (F::ONE, F::ONE, F::ONE),
101 (F::ONE, F::NEG_ONE, F::NEG_ONE),
102 (F::ONE, F::INFINITY, F::ONE),
103 (F::ONE, F::NEG_INFINITY, F::NEG_INFINITY),
104 (F::ONE, F::NAN, F::ONE),
105 (F::ONE, F::NEG_NAN, F::ONE),
106 (F::NEG_ONE, F::ZERO, F::NEG_ONE),
107 (F::NEG_ONE, F::NEG_ZERO, F::NEG_ONE),
108 (F::NEG_ONE, F::ONE, F::NEG_ONE),
109 (F::NEG_ONE, F::NEG_ONE, F::NEG_ONE),
110 (F::NEG_ONE, F::INFINITY, F::NEG_ONE),
111 (F::NEG_ONE, F::NEG_INFINITY, F::NEG_INFINITY),
112 (F::NEG_ONE, F::NAN, F::NEG_ONE),
113 (F::NEG_ONE, F::NEG_NAN, F::NEG_ONE),
114 (F::INFINITY, F::ZERO, F::ZERO),
115 (F::INFINITY, F::NEG_ZERO, F::NEG_ZERO),
116 (F::INFINITY, F::ONE, F::ONE),
117 (F::INFINITY, F::NEG_ONE, F::NEG_ONE),
118 (F::INFINITY, F::INFINITY, F::INFINITY),
119 (F::INFINITY, F::NEG_INFINITY, F::NEG_INFINITY),
120 (F::INFINITY, F::NAN, F::INFINITY),
121 (F::INFINITY, F::NEG_NAN, F::INFINITY),
122 (F::NEG_INFINITY, F::ZERO, F::NEG_INFINITY),
123 (F::NEG_INFINITY, F::NEG_ZERO, F::NEG_INFINITY),
124 (F::NEG_INFINITY, F::ONE, F::NEG_INFINITY),
125 (F::NEG_INFINITY, F::NEG_ONE, F::NEG_INFINITY),
126 (F::NEG_INFINITY, F::INFINITY, F::NEG_INFINITY),
127 (F::NEG_INFINITY, F::NEG_INFINITY, F::NEG_INFINITY),
128 (F::NEG_INFINITY, F::NAN, F::NEG_INFINITY),
129 (F::NEG_INFINITY, F::NEG_NAN, F::NEG_INFINITY),
130 (F::NAN, F::ZERO, F::ZERO),
131 (F::NAN, F::NEG_ZERO, F::NEG_ZERO),
132 (F::NAN, F::ONE, F::ONE),
133 (F::NAN, F::NEG_ONE, F::NEG_ONE),
134 (F::NAN, F::INFINITY, F::INFINITY),
135 (F::NAN, F::NEG_INFINITY, F::NEG_INFINITY),
136 (F::NAN, F::NAN, F::NAN),
137 (F::NEG_NAN, F::ZERO, F::ZERO),
138 (F::NEG_NAN, F::NEG_ZERO, F::NEG_ZERO),
139 (F::NEG_NAN, F::ONE, F::ONE),
140 (F::NEG_NAN, F::NEG_ONE, F::NEG_ONE),
141 (F::NEG_NAN, F::INFINITY, F::INFINITY),
142 (F::NEG_NAN, F::NEG_INFINITY, F::NEG_INFINITY),
143 ];
144
145 for (x, y, res) in cases {
146 let val = f(x, y);
147 assert_biteq!(val, res, "fmin({}, {})", Hexf(x), Hexf(y));
148 }
149
150 assert_eq!(f(F::ZERO, F::NEG_ZERO), F::ZERO);
152 assert_eq!(f(F::NEG_ZERO, F::ZERO), F::ZERO);
153 assert!(f(F::NAN, F::NEG_NAN).is_nan());
154 assert!(f(F::NEG_NAN, F::NAN).is_nan());
155 assert!(f(F::NEG_NAN, F::NEG_NAN).is_nan());
156 }
157
158 #[test]
159 #[cfg(f16_enabled)]
160 fn fmin_spec_tests_f16() {
161 fmin_spec_test::<f16>(fminf16);
162 }
163
164 #[test]
165 fn fmin_spec_tests_f32() {
166 fmin_spec_test::<f32>(fminf);
167 }
168
169 #[test]
170 fn fmin_spec_tests_f64() {
171 fmin_spec_test::<f64>(fmin);
172 }
173
174 #[test]
175 #[cfg(f128_enabled)]
176 fn fmin_spec_tests_f128() {
177 fmin_spec_test::<f128>(fminf128);
178 }
179
180 fn fmax_spec_test<F: Float>(f: impl Fn(F, F) -> F) {
181 let cases = [
182 (F::ZERO, F::ZERO, F::ZERO),
183 (F::ZERO, F::ONE, F::ONE),
184 (F::ZERO, F::NEG_ONE, F::ZERO),
185 (F::ZERO, F::INFINITY, F::INFINITY),
186 (F::ZERO, F::NEG_INFINITY, F::ZERO),
187 (F::ZERO, F::NAN, F::ZERO),
188 (F::ZERO, F::NEG_NAN, F::ZERO),
189 (F::NEG_ZERO, F::NEG_ZERO, F::NEG_ZERO),
190 (F::NEG_ZERO, F::ONE, F::ONE),
191 (F::NEG_ZERO, F::NEG_ONE, F::NEG_ZERO),
192 (F::NEG_ZERO, F::INFINITY, F::INFINITY),
193 (F::NEG_ZERO, F::NEG_INFINITY, F::NEG_ZERO),
194 (F::NEG_ZERO, F::NAN, F::NEG_ZERO),
195 (F::NEG_ZERO, F::NEG_NAN, F::NEG_ZERO),
196 (F::ONE, F::ZERO, F::ONE),
197 (F::ONE, F::NEG_ZERO, F::ONE),
198 (F::ONE, F::ONE, F::ONE),
199 (F::ONE, F::NEG_ONE, F::ONE),
200 (F::ONE, F::INFINITY, F::INFINITY),
201 (F::ONE, F::NEG_INFINITY, F::ONE),
202 (F::ONE, F::NAN, F::ONE),
203 (F::ONE, F::NEG_NAN, F::ONE),
204 (F::NEG_ONE, F::ZERO, F::ZERO),
205 (F::NEG_ONE, F::NEG_ZERO, F::NEG_ZERO),
206 (F::NEG_ONE, F::ONE, F::ONE),
207 (F::NEG_ONE, F::NEG_ONE, F::NEG_ONE),
208 (F::NEG_ONE, F::INFINITY, F::INFINITY),
209 (F::NEG_ONE, F::NEG_INFINITY, F::NEG_ONE),
210 (F::NEG_ONE, F::NAN, F::NEG_ONE),
211 (F::NEG_ONE, F::NEG_NAN, F::NEG_ONE),
212 (F::INFINITY, F::ZERO, F::INFINITY),
213 (F::INFINITY, F::NEG_ZERO, F::INFINITY),
214 (F::INFINITY, F::ONE, F::INFINITY),
215 (F::INFINITY, F::NEG_ONE, F::INFINITY),
216 (F::INFINITY, F::INFINITY, F::INFINITY),
217 (F::INFINITY, F::NEG_INFINITY, F::INFINITY),
218 (F::INFINITY, F::NAN, F::INFINITY),
219 (F::INFINITY, F::NEG_NAN, F::INFINITY),
220 (F::NEG_INFINITY, F::ZERO, F::ZERO),
221 (F::NEG_INFINITY, F::NEG_ZERO, F::NEG_ZERO),
222 (F::NEG_INFINITY, F::ONE, F::ONE),
223 (F::NEG_INFINITY, F::NEG_ONE, F::NEG_ONE),
224 (F::NEG_INFINITY, F::INFINITY, F::INFINITY),
225 (F::NEG_INFINITY, F::NEG_INFINITY, F::NEG_INFINITY),
226 (F::NEG_INFINITY, F::NAN, F::NEG_INFINITY),
227 (F::NEG_INFINITY, F::NEG_NAN, F::NEG_INFINITY),
228 (F::NAN, F::ZERO, F::ZERO),
229 (F::NAN, F::NEG_ZERO, F::NEG_ZERO),
230 (F::NAN, F::ONE, F::ONE),
231 (F::NAN, F::NEG_ONE, F::NEG_ONE),
232 (F::NAN, F::INFINITY, F::INFINITY),
233 (F::NAN, F::NEG_INFINITY, F::NEG_INFINITY),
234 (F::NAN, F::NAN, F::NAN),
235 (F::NEG_NAN, F::ZERO, F::ZERO),
236 (F::NEG_NAN, F::NEG_ZERO, F::NEG_ZERO),
237 (F::NEG_NAN, F::ONE, F::ONE),
238 (F::NEG_NAN, F::NEG_ONE, F::NEG_ONE),
239 (F::NEG_NAN, F::INFINITY, F::INFINITY),
240 (F::NEG_NAN, F::NEG_INFINITY, F::NEG_INFINITY),
241 ];
242
243 for (x, y, res) in cases {
244 let val = f(x, y);
245 assert_biteq!(val, res, "fmax({}, {})", Hexf(x), Hexf(y));
246 }
247
248 assert_eq!(f(F::ZERO, F::NEG_ZERO), F::ZERO);
250 assert_eq!(f(F::NEG_ZERO, F::ZERO), F::ZERO);
251 assert!(f(F::NAN, F::NEG_NAN).is_nan());
252 assert!(f(F::NEG_NAN, F::NAN).is_nan());
253 assert!(f(F::NEG_NAN, F::NEG_NAN).is_nan());
254 }
255
256 #[test]
257 #[cfg(f16_enabled)]
258 fn fmax_spec_tests_f16() {
259 fmax_spec_test::<f16>(fmaxf16);
260 }
261
262 #[test]
263 fn fmax_spec_tests_f32() {
264 fmax_spec_test::<f32>(fmaxf);
265 }
266
267 #[test]
268 fn fmax_spec_tests_f64() {
269 fmax_spec_test::<f64>(fmax);
270 }
271
272 #[test]
273 #[cfg(f128_enabled)]
274 fn fmax_spec_tests_f128() {
275 fmax_spec_test::<f128>(fmaxf128);
276 }
277}