@@ -311,6 +311,95 @@ fn test_f64() {
311311 ) ;
312312}
313313
314+ fn test_casts ( ) {
315+ let all1_payload_32 = u32_ones ( 22 ) ;
316+ let all1_payload_64 = u64_ones ( 51 ) ;
317+ let left1_payload_64 = ( all1_payload_32 as u64 ) << ( 51 - 22 ) ;
318+
319+ // 64-to-32
320+ check_all_outcomes (
321+ HashSet :: from_iter ( [ F32 :: nan ( Pos , Quiet , 0 ) , F32 :: nan ( Neg , Quiet , 0 ) ] ) ,
322+ || F32 :: from ( F64 :: nan ( Pos , Quiet , 0 ) . as_f64 ( ) as f32 ) ,
323+ ) ;
324+ // The preferred payload is always a possibility.
325+ check_all_outcomes (
326+ HashSet :: from_iter ( [
327+ F32 :: nan ( Pos , Quiet , 0 ) ,
328+ F32 :: nan ( Neg , Quiet , 0 ) ,
329+ F32 :: nan ( Pos , Quiet , all1_payload_32) ,
330+ F32 :: nan ( Neg , Quiet , all1_payload_32) ,
331+ ] ) ,
332+ || F32 :: from ( F64 :: nan ( Pos , Quiet , all1_payload_64) . as_f64 ( ) as f32 ) ,
333+ ) ;
334+ // If the input is signaling, then the output *may* also be signaling.
335+ check_all_outcomes (
336+ HashSet :: from_iter ( [
337+ F32 :: nan ( Pos , Quiet , 0 ) ,
338+ F32 :: nan ( Neg , Quiet , 0 ) ,
339+ F32 :: nan ( Pos , Quiet , all1_payload_32) ,
340+ F32 :: nan ( Neg , Quiet , all1_payload_32) ,
341+ F32 :: nan ( Pos , Signaling , all1_payload_32) ,
342+ F32 :: nan ( Neg , Signaling , all1_payload_32) ,
343+ ] ) ,
344+ || F32 :: from ( F64 :: nan ( Pos , Signaling , all1_payload_64) . as_f64 ( ) as f32 ) ,
345+ ) ;
346+ // Check that the low bits are gone (not the high bits).
347+ check_all_outcomes (
348+ HashSet :: from_iter ( [
349+ F32 :: nan ( Pos , Quiet , 0 ) ,
350+ F32 :: nan ( Neg , Quiet , 0 ) ,
351+ ] ) ,
352+ || F32 :: from ( F64 :: nan ( Pos , Quiet , 1 ) . as_f64 ( ) as f32 ) ,
353+ ) ;
354+ check_all_outcomes (
355+ HashSet :: from_iter ( [
356+ F32 :: nan ( Pos , Quiet , 0 ) ,
357+ F32 :: nan ( Neg , Quiet , 0 ) ,
358+ F32 :: nan ( Pos , Quiet , 1 ) ,
359+ F32 :: nan ( Neg , Quiet , 1 ) ,
360+ ] ) ,
361+ || F32 :: from ( F64 :: nan ( Pos , Quiet , 1 << ( 51 -22 ) ) . as_f64 ( ) as f32 ) ,
362+ ) ;
363+ check_all_outcomes (
364+ HashSet :: from_iter ( [
365+ F32 :: nan ( Pos , Quiet , 0 ) ,
366+ F32 :: nan ( Neg , Quiet , 0 ) ,
367+ // The `1` payload becomes `0`, and the `0` payload cannot be signaling,
368+ // so these are the only options.
369+ ] ) ,
370+ || F32 :: from ( F64 :: nan ( Pos , Signaling , 1 ) . as_f64 ( ) as f32 ) ,
371+ ) ;
372+
373+ // 32-to-64
374+ check_all_outcomes (
375+ HashSet :: from_iter ( [ F64 :: nan ( Pos , Quiet , 0 ) , F64 :: nan ( Neg , Quiet , 0 ) ] ) ,
376+ || F64 :: from ( F32 :: nan ( Pos , Quiet , 0 ) . as_f32 ( ) as f64 ) ,
377+ ) ;
378+ // The preferred payload is always a possibility.
379+ // Also checks that 0s are added on the right.
380+ check_all_outcomes (
381+ HashSet :: from_iter ( [
382+ F64 :: nan ( Pos , Quiet , 0 ) ,
383+ F64 :: nan ( Neg , Quiet , 0 ) ,
384+ F64 :: nan ( Pos , Quiet , left1_payload_64) ,
385+ F64 :: nan ( Neg , Quiet , left1_payload_64) ,
386+ ] ) ,
387+ || F64 :: from ( F32 :: nan ( Pos , Quiet , all1_payload_32) . as_f32 ( ) as f64 ) ,
388+ ) ;
389+ // If the input is signaling, then the output *may* also be signaling.
390+ check_all_outcomes (
391+ HashSet :: from_iter ( [
392+ F64 :: nan ( Pos , Quiet , 0 ) ,
393+ F64 :: nan ( Neg , Quiet , 0 ) ,
394+ F64 :: nan ( Pos , Quiet , left1_payload_64) ,
395+ F64 :: nan ( Neg , Quiet , left1_payload_64) ,
396+ F64 :: nan ( Pos , Signaling , left1_payload_64) ,
397+ F64 :: nan ( Neg , Signaling , left1_payload_64) ,
398+ ] ) ,
399+ || F64 :: from ( F32 :: nan ( Pos , Signaling , all1_payload_32) . as_f32 ( ) as f64 ) ,
400+ ) ;
401+ }
402+
314403fn main ( ) {
315404 // Check our constants against std, just to be sure.
316405 // We add 1 since our numbers are the number of bits stored
@@ -321,4 +410,5 @@ fn main() {
321410
322411 test_f32 ( ) ;
323412 test_f64 ( ) ;
413+ test_casts ( ) ;
324414}
0 commit comments