@@ -2,34 +2,70 @@ use std::num::FpCategory as Fp;
22use std:: ops:: { Add , Div , Mul , Rem , Sub } ;
33
44trait TestableFloat {
5+ /// Unsigned int with the same size, for converting to/from bits.
6+ type Int ;
57 /// Set the default tolerance for float comparison based on the type.
68 const APPROX : Self ;
79 const MIN_POSITIVE_NORMAL : Self ;
810 const MAX_SUBNORMAL : Self ;
11+ /// Smallest number
12+ const TINY : Self ;
13+ /// Next smallest number
14+ const TINY_UP : Self ;
15+ /// Exponent = 0b11...10, Significand 0b1111..10. Min val > 0
16+ const MAX_DOWN : Self ;
17+ /// First pattern over the mantissa
18+ const NAN_MASK1 : Self :: Int ;
19+ /// Second pattern over the mantissa
20+ const NAN_MASK2 : Self :: Int ;
921}
1022
1123impl TestableFloat for f16 {
24+ type Int = u16 ;
1225 const APPROX : Self = 1e-3 ;
1326 const MIN_POSITIVE_NORMAL : Self = Self :: MIN_POSITIVE ;
1427 const MAX_SUBNORMAL : Self = Self :: MIN_POSITIVE . next_down ( ) ;
28+ const TINY : Self = Self :: from_bits ( 0x1 ) ;
29+ const TINY_UP : Self = Self :: from_bits ( 0x2 ) ;
30+ const MAX_DOWN : Self = Self :: from_bits ( 0x7bfe ) ;
31+ const NAN_MASK1 : Self :: Int = 0x02aa ;
32+ const NAN_MASK2 : Self :: Int = 0x0155 ;
1533}
1634
1735impl TestableFloat for f32 {
36+ type Int = u32 ;
1837 const APPROX : Self = 1e-6 ;
1938 const MIN_POSITIVE_NORMAL : Self = Self :: MIN_POSITIVE ;
2039 const MAX_SUBNORMAL : Self = Self :: MIN_POSITIVE . next_down ( ) ;
40+ const TINY : Self = Self :: from_bits ( 0x1 ) ;
41+ const TINY_UP : Self = Self :: from_bits ( 0x2 ) ;
42+ const MAX_DOWN : Self = Self :: from_bits ( 0x7f7f_fffe ) ;
43+ const NAN_MASK1 : Self :: Int = 0x002a_aaaa ;
44+ const NAN_MASK2 : Self :: Int = 0x0055_5555 ;
2145}
2246
2347impl TestableFloat for f64 {
48+ type Int = u64 ;
2449 const APPROX : Self = 1e-6 ;
2550 const MIN_POSITIVE_NORMAL : Self = Self :: MIN_POSITIVE ;
2651 const MAX_SUBNORMAL : Self = Self :: MIN_POSITIVE . next_down ( ) ;
52+ const TINY : Self = Self :: from_bits ( 0x1 ) ;
53+ const TINY_UP : Self = Self :: from_bits ( 0x2 ) ;
54+ const MAX_DOWN : Self = Self :: from_bits ( 0x7fef_ffff_ffff_fffe ) ;
55+ const NAN_MASK1 : Self :: Int = 0x000a_aaaa_aaaa_aaaa ;
56+ const NAN_MASK2 : Self :: Int = 0x0005_5555_5555_5555 ;
2757}
2858
2959impl TestableFloat for f128 {
60+ type Int = u128 ;
3061 const APPROX : Self = 1e-9 ;
3162 const MIN_POSITIVE_NORMAL : Self = Self :: MIN_POSITIVE ;
3263 const MAX_SUBNORMAL : Self = Self :: MIN_POSITIVE . next_down ( ) ;
64+ const TINY : Self = Self :: from_bits ( 0x1 ) ;
65+ const TINY_UP : Self = Self :: from_bits ( 0x2 ) ;
66+ const MAX_DOWN : Self = Self :: from_bits ( 0x7ffefffffffffffffffffffffffffffe ) ;
67+ const NAN_MASK1 : Self :: Int = 0x0000aaaaaaaaaaaaaaaaaaaaaaaaaaaa ;
68+ const NAN_MASK2 : Self :: Int = 0x00005555555555555555555555555555 ;
3369}
3470
3571/// Determine the tolerance for values of the argument type.
@@ -1019,3 +1055,36 @@ float_test! {
10191055 assert!( ( -Float :: NAN ) . is_sign_negative( ) ) ;
10201056 }
10211057}
1058+
1059+ float_test ! {
1060+ name: next_up,
1061+ attrs: {
1062+ f16: #[ cfg( any( miri, target_has_reliable_f16) ) ] ,
1063+ f128: #[ cfg( any( miri, target_has_reliable_f128) ) ] ,
1064+ } ,
1065+ test<Float > {
1066+ let one: Float = 1.0 ;
1067+ let zero: Float = 0.0 ;
1068+ assert_biteq!( Float :: NEG_INFINITY . next_up( ) , Float :: MIN ) ;
1069+ assert_biteq!( Float :: MIN . next_up( ) , -Float :: MAX_DOWN ) ;
1070+ assert_biteq!( ( -one - Float :: EPSILON ) . next_up( ) , -one) ;
1071+ assert_biteq!( ( -Float :: MIN_POSITIVE_NORMAL ) . next_up( ) , -Float :: MAX_SUBNORMAL ) ;
1072+ assert_biteq!( ( -Float :: TINY_UP ) . next_up( ) , -Float :: TINY ) ;
1073+ assert_biteq!( ( -Float :: TINY ) . next_up( ) , -zero) ;
1074+ assert_biteq!( ( -zero) . next_up( ) , Float :: TINY ) ;
1075+ assert_biteq!( zero. next_up( ) , Float :: TINY ) ;
1076+ assert_biteq!( Float :: TINY . next_up( ) , Float :: TINY_UP ) ;
1077+ assert_biteq!( Float :: MAX_SUBNORMAL . next_up( ) , Float :: MIN_POSITIVE_NORMAL ) ;
1078+ assert_biteq!( one. next_up( ) , 1.0 + Float :: EPSILON ) ;
1079+ assert_biteq!( Float :: MAX . next_up( ) , Float :: INFINITY ) ;
1080+ assert_biteq!( Float :: INFINITY . next_up( ) , Float :: INFINITY ) ;
1081+
1082+ // Check that NaNs roundtrip.
1083+ let nan0 = Float :: NAN ;
1084+ let nan1 = Float :: from_bits( Float :: NAN . to_bits( ) ^ Float :: NAN_MASK1 ) ;
1085+ let nan2 = Float :: from_bits( Float :: NAN . to_bits( ) ^ Float :: NAN_MASK2 ) ;
1086+ assert_biteq!( nan0. next_up( ) , nan0) ;
1087+ assert_biteq!( nan1. next_up( ) , nan1) ;
1088+ assert_biteq!( nan2. next_up( ) , nan2) ;
1089+ }
1090+ }
0 commit comments