@@ -6,30 +6,65 @@ trait TestableFloat {
6
6
const APPROX : Self ;
7
7
const MIN_POSITIVE_NORMAL : Self ;
8
8
const MAX_SUBNORMAL : Self ;
9
+ /// Smallest number
10
+ const TINY : Self ;
11
+ /// Next smallest number
12
+ const TINY_UP : Self ;
13
+ /// Exponent = 0b11...10, Significand 0b1111..10. Min val > 0
14
+ const MAX_DOWN : Self ;
15
+ type Bits ;
16
+ /// First pattern over the mantissa
17
+ const NAN_MASK1 : Self :: Bits ;
18
+ /// Second pattern over the mantissa
19
+ const NAN_MASK2 : Self :: Bits ;
9
20
}
10
21
11
22
impl TestableFloat for f16 {
12
23
const APPROX : Self = 1e-3 ;
13
24
const MIN_POSITIVE_NORMAL : Self = Self :: MIN_POSITIVE ;
14
25
const MAX_SUBNORMAL : Self = Self :: MIN_POSITIVE . next_down ( ) ;
26
+ const TINY : Self = Self :: from_bits ( 0x1 ) ;
27
+ const TINY_UP : Self = Self :: from_bits ( 0x2 ) ;
28
+ const MAX_DOWN : Self = Self :: from_bits ( 0x7bfe ) ;
29
+ type Bits = u16 ;
30
+ const NAN_MASK1 : Self :: Bits = 0x02aa ;
31
+ const NAN_MASK2 : Self :: Bits = 0x0155 ;
15
32
}
16
33
17
34
impl TestableFloat for f32 {
18
35
const APPROX : Self = 1e-6 ;
19
36
const MIN_POSITIVE_NORMAL : Self = Self :: MIN_POSITIVE ;
20
37
const MAX_SUBNORMAL : Self = Self :: MIN_POSITIVE . next_down ( ) ;
38
+ const TINY : Self = Self :: from_bits ( 0x1 ) ;
39
+ const TINY_UP : Self = Self :: from_bits ( 0x2 ) ;
40
+ const MAX_DOWN : Self = Self :: from_bits ( 0x7f7f_fffe ) ;
41
+ type Bits = u32 ;
42
+ const NAN_MASK1 : Self :: Bits = 0x002a_aaaa ;
43
+ const NAN_MASK2 : Self :: Bits = 0x0055_5555 ;
21
44
}
22
45
23
46
impl TestableFloat for f64 {
24
47
const APPROX : Self = 1e-6 ;
25
48
const MIN_POSITIVE_NORMAL : Self = Self :: MIN_POSITIVE ;
26
49
const MAX_SUBNORMAL : Self = Self :: MIN_POSITIVE . next_down ( ) ;
50
+ const TINY : Self = Self :: from_bits ( 0x1 ) ;
51
+ const TINY_UP : Self = Self :: from_bits ( 0x2 ) ;
52
+ const MAX_DOWN : Self = Self :: from_bits ( 0x7fef_ffff_ffff_fffe ) ;
53
+ type Bits = u64 ;
54
+ const NAN_MASK1 : Self :: Bits = 0x000a_aaaa_aaaa_aaaa ;
55
+ const NAN_MASK2 : Self :: Bits = 0x0005_5555_5555_5555 ;
27
56
}
28
57
29
58
impl TestableFloat for f128 {
30
59
const APPROX : Self = 1e-9 ;
31
60
const MIN_POSITIVE_NORMAL : Self = Self :: MIN_POSITIVE ;
32
61
const MAX_SUBNORMAL : Self = Self :: MIN_POSITIVE . next_down ( ) ;
62
+ const TINY : Self = Self :: from_bits ( 0x1 ) ;
63
+ const TINY_UP : Self = Self :: from_bits ( 0x2 ) ;
64
+ const MAX_DOWN : Self = Self :: from_bits ( 0x7ffefffffffffffffffffffffffffffe ) ;
65
+ type Bits = u128 ;
66
+ const NAN_MASK1 : Self :: Bits = 0x0000aaaaaaaaaaaaaaaaaaaaaaaaaaaa ;
67
+ const NAN_MASK2 : Self :: Bits = 0x00005555555555555555555555555555 ;
33
68
}
34
69
35
70
/// Determine the tolerance for values of the argument type.
@@ -1019,3 +1054,36 @@ float_test! {
1019
1054
assert!( ( -Float :: NAN ) . is_sign_negative( ) ) ;
1020
1055
}
1021
1056
}
1057
+
1058
+ float_test ! {
1059
+ name: next_up,
1060
+ attrs: {
1061
+ f16: #[ cfg( any( miri, target_has_reliable_f16) ) ] ,
1062
+ f128: #[ cfg( any( miri, target_has_reliable_f128) ) ] ,
1063
+ } ,
1064
+ test<Float > {
1065
+ let one: Float = 1.0 ;
1066
+ let zero: Float = 0.0 ;
1067
+ assert_biteq!( Float :: NEG_INFINITY . next_up( ) , Float :: MIN ) ;
1068
+ assert_biteq!( Float :: MIN . next_up( ) , -Float :: MAX_DOWN ) ;
1069
+ assert_biteq!( ( -one - Float :: EPSILON ) . next_up( ) , -one) ;
1070
+ assert_biteq!( ( -Float :: MIN_POSITIVE_NORMAL ) . next_up( ) , -Float :: MAX_SUBNORMAL ) ;
1071
+ assert_biteq!( ( -Float :: TINY_UP ) . next_up( ) , -Float :: TINY ) ;
1072
+ assert_biteq!( ( -Float :: TINY ) . next_up( ) , -zero) ;
1073
+ assert_biteq!( ( -zero) . next_up( ) , Float :: TINY ) ;
1074
+ assert_biteq!( zero. next_up( ) , Float :: TINY ) ;
1075
+ assert_biteq!( Float :: TINY . next_up( ) , Float :: TINY_UP ) ;
1076
+ assert_biteq!( Float :: MAX_SUBNORMAL . next_up( ) , Float :: MIN_POSITIVE_NORMAL ) ;
1077
+ assert_biteq!( one. next_up( ) , 1.0 + Float :: EPSILON ) ;
1078
+ assert_biteq!( Float :: MAX . next_up( ) , Float :: INFINITY ) ;
1079
+ assert_biteq!( Float :: INFINITY . next_up( ) , Float :: INFINITY ) ;
1080
+
1081
+ // Check that NaNs roundtrip.
1082
+ let nan0 = Float :: NAN ;
1083
+ let nan1 = Float :: from_bits( Float :: NAN . to_bits( ) ^ Float :: NAN_MASK1 ) ;
1084
+ let nan2 = Float :: from_bits( Float :: NAN . to_bits( ) ^ Float :: NAN_MASK2 ) ;
1085
+ assert_biteq!( nan0. next_up( ) , nan0) ;
1086
+ assert_biteq!( nan1. next_up( ) , nan1) ;
1087
+ assert_biteq!( nan2. next_up( ) , nan2) ;
1088
+ }
1089
+ }
0 commit comments