@@ -77,9 +77,12 @@ pub fn fmaxf128(x: f128, y: f128) -> f128 {
7777#[ cfg( test) ]
7878mod tests {
7979 use super :: * ;
80+ use crate :: support:: hex_float:: Hexi ;
8081 use crate :: support:: { Float , Hexf } ;
8182
8283 fn fmin_spec_test < F : Float > ( f : impl Fn ( F , F ) -> F ) {
84+ // Note that (YaN, sNaN) and (sNaN, YaN) results differ from 754-2008. This is intentional,
85+ // see comments in the generic implementations.
8386 let cases = [
8487 ( F :: ZERO , F :: ZERO , F :: ZERO ) ,
8588 ( F :: ZERO , F :: ONE , F :: ZERO ) ,
@@ -88,13 +91,17 @@ mod tests {
8891 ( F :: ZERO , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
8992 ( F :: ZERO , F :: NAN , F :: ZERO ) ,
9093 ( F :: ZERO , F :: NEG_NAN , F :: ZERO ) ,
94+ ( F :: ZERO , F :: SNAN , F :: ZERO ) ,
95+ ( F :: ZERO , F :: NEG_SNAN , F :: ZERO ) ,
9196 ( F :: NEG_ZERO , F :: NEG_ZERO , F :: NEG_ZERO ) ,
9297 ( F :: NEG_ZERO , F :: ONE , F :: NEG_ZERO ) ,
9398 ( F :: NEG_ZERO , F :: NEG_ONE , F :: NEG_ONE ) ,
9499 ( F :: NEG_ZERO , F :: INFINITY , F :: NEG_ZERO ) ,
95100 ( F :: NEG_ZERO , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
96101 ( F :: NEG_ZERO , F :: NAN , F :: NEG_ZERO ) ,
97102 ( F :: NEG_ZERO , F :: NEG_NAN , F :: NEG_ZERO ) ,
103+ ( F :: NEG_ZERO , F :: SNAN , F :: NEG_ZERO ) ,
104+ ( F :: NEG_ZERO , F :: NEG_SNAN , F :: NEG_ZERO ) ,
98105 ( F :: ONE , F :: ZERO , F :: ZERO ) ,
99106 ( F :: ONE , F :: NEG_ZERO , F :: NEG_ZERO ) ,
100107 ( F :: ONE , F :: ONE , F :: ONE ) ,
@@ -103,6 +110,8 @@ mod tests {
103110 ( F :: ONE , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
104111 ( F :: ONE , F :: NAN , F :: ONE ) ,
105112 ( F :: ONE , F :: NEG_NAN , F :: ONE ) ,
113+ ( F :: ONE , F :: SNAN , F :: ONE ) ,
114+ ( F :: ONE , F :: NEG_SNAN , F :: ONE ) ,
106115 ( F :: NEG_ONE , F :: ZERO , F :: NEG_ONE ) ,
107116 ( F :: NEG_ONE , F :: NEG_ZERO , F :: NEG_ONE ) ,
108117 ( F :: NEG_ONE , F :: ONE , F :: NEG_ONE ) ,
@@ -111,6 +120,8 @@ mod tests {
111120 ( F :: NEG_ONE , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
112121 ( F :: NEG_ONE , F :: NAN , F :: NEG_ONE ) ,
113122 ( F :: NEG_ONE , F :: NEG_NAN , F :: NEG_ONE ) ,
123+ ( F :: NEG_ONE , F :: SNAN , F :: NEG_ONE ) ,
124+ ( F :: NEG_ONE , F :: NEG_SNAN , F :: NEG_ONE ) ,
114125 ( F :: INFINITY , F :: ZERO , F :: ZERO ) ,
115126 ( F :: INFINITY , F :: NEG_ZERO , F :: NEG_ZERO ) ,
116127 ( F :: INFINITY , F :: ONE , F :: ONE ) ,
@@ -119,6 +130,8 @@ mod tests {
119130 ( F :: INFINITY , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
120131 ( F :: INFINITY , F :: NAN , F :: INFINITY ) ,
121132 ( F :: INFINITY , F :: NEG_NAN , F :: INFINITY ) ,
133+ ( F :: INFINITY , F :: SNAN , F :: INFINITY ) ,
134+ ( F :: INFINITY , F :: NEG_SNAN , F :: INFINITY ) ,
122135 ( F :: NEG_INFINITY , F :: ZERO , F :: NEG_INFINITY ) ,
123136 ( F :: NEG_INFINITY , F :: NEG_ZERO , F :: NEG_INFINITY ) ,
124137 ( F :: NEG_INFINITY , F :: ONE , F :: NEG_INFINITY ) ,
@@ -127,6 +140,8 @@ mod tests {
127140 ( F :: NEG_INFINITY , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
128141 ( F :: NEG_INFINITY , F :: NAN , F :: NEG_INFINITY ) ,
129142 ( F :: NEG_INFINITY , F :: NEG_NAN , F :: NEG_INFINITY ) ,
143+ ( F :: NEG_INFINITY , F :: SNAN , F :: NEG_INFINITY ) ,
144+ ( F :: NEG_INFINITY , F :: NEG_SNAN , F :: NEG_INFINITY ) ,
130145 ( F :: NAN , F :: ZERO , F :: ZERO ) ,
131146 ( F :: NAN , F :: NEG_ZERO , F :: NEG_ZERO ) ,
132147 ( F :: NAN , F :: ONE , F :: ONE ) ,
@@ -140,19 +155,45 @@ mod tests {
140155 ( F :: NEG_NAN , F :: NEG_ONE , F :: NEG_ONE ) ,
141156 ( F :: NEG_NAN , F :: INFINITY , F :: INFINITY ) ,
142157 ( F :: NEG_NAN , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
158+ ( F :: SNAN , F :: ZERO , F :: ZERO ) ,
159+ ( F :: SNAN , F :: NEG_ZERO , F :: NEG_ZERO ) ,
160+ ( F :: SNAN , F :: ONE , F :: ONE ) ,
161+ ( F :: SNAN , F :: NEG_ONE , F :: NEG_ONE ) ,
162+ ( F :: SNAN , F :: INFINITY , F :: INFINITY ) ,
163+ ( F :: SNAN , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
164+ ( F :: SNAN , F :: NAN , F :: QSNAN ) ,
165+ ( F :: NEG_SNAN , F :: ZERO , F :: ZERO ) ,
166+ ( F :: NEG_SNAN , F :: NEG_ZERO , F :: NEG_ZERO ) ,
167+ ( F :: NEG_SNAN , F :: ONE , F :: ONE ) ,
168+ ( F :: NEG_SNAN , F :: NEG_ONE , F :: NEG_ONE ) ,
169+ ( F :: NEG_SNAN , F :: INFINITY , F :: INFINITY ) ,
170+ ( F :: NEG_SNAN , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
143171 ] ;
144172
145173 for ( x, y, res) in cases {
146174 let val = f ( x, y) ;
147175 assert_biteq ! ( val, res, "fmin({}, {})" , Hexf ( x) , Hexf ( y) ) ;
148176 }
149177
150- // Ordering between zeros and NaNs does not matter
178+ // Ordering between zeros does not matter
151179 assert_eq ! ( f( F :: ZERO , F :: NEG_ZERO ) , F :: ZERO ) ;
152180 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( ) ) ;
181+
182+ // Selection between NaNs does not matter, it just must be quiet
183+ assert ! ( f( F :: NAN , F :: NEG_NAN ) . is_qnan( ) ) ;
184+ assert ! ( f( F :: NAN , F :: NEG_SNAN ) . is_qnan( ) ) ;
185+ assert ! ( f( F :: NAN , F :: SNAN ) . is_qnan( ) ) ;
186+ assert ! ( f( F :: NEG_NAN , F :: NAN ) . is_qnan( ) ) ;
187+ assert ! ( f( F :: NEG_NAN , F :: NEG_NAN ) . is_qnan( ) ) ;
188+ assert ! ( f( F :: NEG_NAN , F :: NEG_SNAN ) . is_qnan( ) ) ;
189+ assert ! ( f( F :: NEG_NAN , F :: SNAN ) . is_qnan( ) ) ;
190+ assert ! ( f( F :: NEG_SNAN , F :: NAN ) . is_qnan( ) ) ;
191+ assert ! ( f( F :: NEG_SNAN , F :: NEG_NAN ) . is_qnan( ) ) ;
192+ assert ! ( f( F :: NEG_SNAN , F :: NEG_SNAN ) . is_qnan( ) ) ;
193+ assert ! ( f( F :: NEG_SNAN , F :: SNAN ) . is_qnan( ) ) ;
194+ assert ! ( f( F :: SNAN , F :: NAN ) . is_qnan( ) ) ;
195+ assert ! ( f( F :: SNAN , F :: NEG_NAN ) . is_qnan( ) ) ;
196+ assert ! ( f( F :: SNAN , F :: NEG_SNAN ) . is_qnan( ) ) ;
156197 }
157198
158199 #[ test]
@@ -186,13 +227,17 @@ mod tests {
186227 ( F :: ZERO , F :: NEG_INFINITY , F :: ZERO ) ,
187228 ( F :: ZERO , F :: NAN , F :: ZERO ) ,
188229 ( F :: ZERO , F :: NEG_NAN , F :: ZERO ) ,
230+ ( F :: ZERO , F :: SNAN , F :: ZERO ) ,
231+ ( F :: ZERO , F :: NEG_SNAN , F :: ZERO ) ,
189232 ( F :: NEG_ZERO , F :: NEG_ZERO , F :: NEG_ZERO ) ,
190233 ( F :: NEG_ZERO , F :: ONE , F :: ONE ) ,
191234 ( F :: NEG_ZERO , F :: NEG_ONE , F :: NEG_ZERO ) ,
192235 ( F :: NEG_ZERO , F :: INFINITY , F :: INFINITY ) ,
193236 ( F :: NEG_ZERO , F :: NEG_INFINITY , F :: NEG_ZERO ) ,
194237 ( F :: NEG_ZERO , F :: NAN , F :: NEG_ZERO ) ,
195238 ( F :: NEG_ZERO , F :: NEG_NAN , F :: NEG_ZERO ) ,
239+ ( F :: NEG_ZERO , F :: SNAN , F :: NEG_ZERO ) ,
240+ ( F :: NEG_ZERO , F :: NEG_SNAN , F :: NEG_ZERO ) ,
196241 ( F :: ONE , F :: ZERO , F :: ONE ) ,
197242 ( F :: ONE , F :: NEG_ZERO , F :: ONE ) ,
198243 ( F :: ONE , F :: ONE , F :: ONE ) ,
@@ -201,6 +246,8 @@ mod tests {
201246 ( F :: ONE , F :: NEG_INFINITY , F :: ONE ) ,
202247 ( F :: ONE , F :: NAN , F :: ONE ) ,
203248 ( F :: ONE , F :: NEG_NAN , F :: ONE ) ,
249+ ( F :: ONE , F :: SNAN , F :: ONE ) ,
250+ ( F :: ONE , F :: NEG_SNAN , F :: ONE ) ,
204251 ( F :: NEG_ONE , F :: ZERO , F :: ZERO ) ,
205252 ( F :: NEG_ONE , F :: NEG_ZERO , F :: NEG_ZERO ) ,
206253 ( F :: NEG_ONE , F :: ONE , F :: ONE ) ,
@@ -209,6 +256,8 @@ mod tests {
209256 ( F :: NEG_ONE , F :: NEG_INFINITY , F :: NEG_ONE ) ,
210257 ( F :: NEG_ONE , F :: NAN , F :: NEG_ONE ) ,
211258 ( F :: NEG_ONE , F :: NEG_NAN , F :: NEG_ONE ) ,
259+ ( F :: NEG_ONE , F :: SNAN , F :: NEG_ONE ) ,
260+ ( F :: NEG_ONE , F :: NEG_SNAN , F :: NEG_ONE ) ,
212261 ( F :: INFINITY , F :: ZERO , F :: INFINITY ) ,
213262 ( F :: INFINITY , F :: NEG_ZERO , F :: INFINITY ) ,
214263 ( F :: INFINITY , F :: ONE , F :: INFINITY ) ,
@@ -217,6 +266,8 @@ mod tests {
217266 ( F :: INFINITY , F :: NEG_INFINITY , F :: INFINITY ) ,
218267 ( F :: INFINITY , F :: NAN , F :: INFINITY ) ,
219268 ( F :: INFINITY , F :: NEG_NAN , F :: INFINITY ) ,
269+ ( F :: INFINITY , F :: SNAN , F :: INFINITY ) ,
270+ ( F :: INFINITY , F :: NEG_SNAN , F :: INFINITY ) ,
220271 ( F :: NEG_INFINITY , F :: ZERO , F :: ZERO ) ,
221272 ( F :: NEG_INFINITY , F :: NEG_ZERO , F :: NEG_ZERO ) ,
222273 ( F :: NEG_INFINITY , F :: ONE , F :: ONE ) ,
@@ -225,6 +276,8 @@ mod tests {
225276 ( F :: NEG_INFINITY , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
226277 ( F :: NEG_INFINITY , F :: NAN , F :: NEG_INFINITY ) ,
227278 ( F :: NEG_INFINITY , F :: NEG_NAN , F :: NEG_INFINITY ) ,
279+ ( F :: NEG_INFINITY , F :: SNAN , F :: NEG_INFINITY ) ,
280+ ( F :: NEG_INFINITY , F :: NEG_SNAN , F :: NEG_INFINITY ) ,
228281 ( F :: NAN , F :: ZERO , F :: ZERO ) ,
229282 ( F :: NAN , F :: NEG_ZERO , F :: NEG_ZERO ) ,
230283 ( F :: NAN , F :: ONE , F :: ONE ) ,
@@ -238,19 +291,53 @@ mod tests {
238291 ( F :: NEG_NAN , F :: NEG_ONE , F :: NEG_ONE ) ,
239292 ( F :: NEG_NAN , F :: INFINITY , F :: INFINITY ) ,
240293 ( F :: NEG_NAN , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
294+ ( F :: SNAN , F :: ZERO , F :: ZERO ) ,
295+ ( F :: SNAN , F :: NEG_ZERO , F :: NEG_ZERO ) ,
296+ ( F :: SNAN , F :: ONE , F :: ONE ) ,
297+ ( F :: SNAN , F :: NEG_ONE , F :: NEG_ONE ) ,
298+ ( F :: SNAN , F :: INFINITY , F :: INFINITY ) ,
299+ ( F :: SNAN , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
300+ ( F :: SNAN , F :: SNAN , F :: QSNAN ) ,
301+ ( F :: NEG_SNAN , F :: ZERO , F :: ZERO ) ,
302+ ( F :: NEG_SNAN , F :: NEG_ZERO , F :: NEG_ZERO ) ,
303+ ( F :: NEG_SNAN , F :: ONE , F :: ONE ) ,
304+ ( F :: NEG_SNAN , F :: NEG_ONE , F :: NEG_ONE ) ,
305+ ( F :: NEG_SNAN , F :: INFINITY , F :: INFINITY ) ,
306+ ( F :: NEG_SNAN , F :: NEG_INFINITY , F :: NEG_INFINITY ) ,
241307 ] ;
242308
243309 for ( x, y, res) in cases {
244310 let val = f ( x, y) ;
245- assert_biteq ! ( val, res, "fmax({}, {})" , Hexf ( x) , Hexf ( y) ) ;
311+ assert_biteq ! (
312+ val,
313+ res,
314+ "fmax({}, {}) ({}, {})" ,
315+ Hexf ( x) ,
316+ Hexf ( y) ,
317+ Hexi ( x. to_bits( ) ) ,
318+ Hexi ( y. to_bits( ) ) ,
319+ ) ;
246320 }
247321
248- // Ordering between zeros and NaNs does not matter
322+ // Ordering between zeros
249323 assert_eq ! ( f( F :: ZERO , F :: NEG_ZERO ) , F :: ZERO ) ;
250324 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( ) ) ;
325+
326+ // Selection between NaNs does not matter, it just must be quiet
327+ assert ! ( f( F :: NAN , F :: NEG_NAN ) . is_qnan( ) ) ;
328+ assert ! ( f( F :: NAN , F :: NEG_SNAN ) . is_qnan( ) ) ;
329+ assert ! ( f( F :: NAN , F :: SNAN ) . is_qnan( ) ) ;
330+ assert ! ( f( F :: NEG_NAN , F :: NAN ) . is_qnan( ) ) ;
331+ assert ! ( f( F :: NEG_NAN , F :: NEG_NAN ) . is_qnan( ) ) ;
332+ assert ! ( f( F :: NEG_NAN , F :: NEG_SNAN ) . is_qnan( ) ) ;
333+ assert ! ( f( F :: NEG_NAN , F :: SNAN ) . is_qnan( ) ) ;
334+ assert ! ( f( F :: NEG_SNAN , F :: NAN ) . is_qnan( ) ) ;
335+ assert ! ( f( F :: NEG_SNAN , F :: NEG_NAN ) . is_qnan( ) ) ;
336+ assert ! ( f( F :: NEG_SNAN , F :: NEG_SNAN ) . is_qnan( ) ) ;
337+ assert ! ( f( F :: NEG_SNAN , F :: SNAN ) . is_qnan( ) ) ;
338+ assert ! ( f( F :: SNAN , F :: NAN ) . is_qnan( ) ) ;
339+ assert ! ( f( F :: SNAN , F :: NEG_NAN ) . is_qnan( ) ) ;
340+ assert ! ( f( F :: SNAN , F :: NEG_SNAN ) . is_qnan( ) ) ;
254341 }
255342
256343 #[ test]
0 commit comments