@@ -2,34 +2,70 @@ use std::num::FpCategory as Fp;
2
2
use std:: ops:: { Add , Div , Mul , Rem , Sub } ;
3
3
4
4
trait TestableFloat {
5
+ /// Unsigned int with the same size, for converting to/from bits.
6
+ type Int ;
5
7
/// Set the default tolerance for float comparison based on the type.
6
8
const APPROX : Self ;
7
9
const MIN_POSITIVE_NORMAL : Self ;
8
10
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 ;
9
21
}
10
22
11
23
impl TestableFloat for f16 {
24
+ type Int = u16 ;
12
25
const APPROX : Self = 1e-3 ;
13
26
const MIN_POSITIVE_NORMAL : Self = Self :: MIN_POSITIVE ;
14
27
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 ;
15
33
}
16
34
17
35
impl TestableFloat for f32 {
36
+ type Int = u32 ;
18
37
const APPROX : Self = 1e-6 ;
19
38
const MIN_POSITIVE_NORMAL : Self = Self :: MIN_POSITIVE ;
20
39
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 ;
21
45
}
22
46
23
47
impl TestableFloat for f64 {
48
+ type Int = u64 ;
24
49
const APPROX : Self = 1e-6 ;
25
50
const MIN_POSITIVE_NORMAL : Self = Self :: MIN_POSITIVE ;
26
51
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 ;
27
57
}
28
58
29
59
impl TestableFloat for f128 {
60
+ type Int = u128 ;
30
61
const APPROX : Self = 1e-9 ;
31
62
const MIN_POSITIVE_NORMAL : Self = Self :: MIN_POSITIVE ;
32
63
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 ;
33
69
}
34
70
35
71
/// Determine the tolerance for values of the argument type.
@@ -1019,3 +1055,36 @@ float_test! {
1019
1055
assert!( ( -Float :: NAN ) . is_sign_negative( ) ) ;
1020
1056
}
1021
1057
}
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