1
1
//! Tests for the `Integer::{ilog,log2,log10}` methods.
2
2
3
+ /// Rounds the argument down to the next integer, except that we account for potential imprecision
4
+ /// in the input, so if `f` is very close to an integer, it will round to that.
5
+ fn round_down_imprecise ( f : f32 ) -> u32 {
6
+ // Rounds up for values less than 16*EPSILON below an integer,
7
+ // and rounds down for everything else.
8
+ ( f + 16.0 * f32:: EPSILON ) as u32
9
+ }
10
+
3
11
#[ test]
4
12
fn checked_ilog ( ) {
5
13
assert_eq ! ( 999u32 . checked_ilog( 10 ) , Some ( 2 ) ) ;
@@ -25,11 +33,19 @@ fn checked_ilog() {
25
33
}
26
34
#[ cfg( not( miri) ) ] // Miri is too slow
27
35
for i in 1 ..=i16:: MAX {
28
- assert_eq ! ( i. checked_ilog( 13 ) , Some ( ( i as f32 ) . log( 13.0 ) as u32 ) , "checking {i}" ) ;
36
+ assert_eq ! (
37
+ i. checked_ilog( 13 ) ,
38
+ Some ( round_down_imprecise( ( i as f32 ) . log( 13.0 ) ) ) ,
39
+ "checking {i}"
40
+ ) ;
29
41
}
30
42
#[ cfg( not( miri) ) ] // Miri is too slow
31
43
for i in 1 ..=u16:: MAX {
32
- assert_eq ! ( i. checked_ilog( 13 ) , Some ( ( i as f32 ) . log( 13.0 ) as u32 ) , "checking {i}" ) ;
44
+ assert_eq ! (
45
+ i. checked_ilog( 13 ) ,
46
+ Some ( round_down_imprecise( ( i as f32 ) . log( 13.0 ) ) ) ,
47
+ "checking {i}"
48
+ ) ;
33
49
}
34
50
}
35
51
@@ -46,36 +62,46 @@ fn checked_ilog2() {
46
62
assert_eq ! ( 0i8 . checked_ilog2( ) , None ) ;
47
63
assert_eq ! ( 0i16 . checked_ilog2( ) , None ) ;
48
64
49
- assert_eq ! ( 8192u16 . checked_ilog2( ) , Some ( ( 8192f32 ) . log2( ) as u32 ) ) ;
50
- assert_eq ! ( 32768u16 . checked_ilog2( ) , Some ( ( 32768f32 ) . log2( ) as u32 ) ) ;
51
- assert_eq ! ( 8192i16 . checked_ilog2( ) , Some ( ( 8192f32 ) . log2( ) as u32 ) ) ;
65
+ assert_eq ! ( 8192u16 . checked_ilog2( ) , Some ( round_down_imprecise ( ( 8192f32 ) . log2( ) ) ) ) ;
66
+ assert_eq ! ( 32768u16 . checked_ilog2( ) , Some ( round_down_imprecise ( ( 32768f32 ) . log2( ) ) ) ) ;
67
+ assert_eq ! ( 8192i16 . checked_ilog2( ) , Some ( round_down_imprecise ( ( 8192f32 ) . log2( ) ) ) ) ;
52
68
53
69
for i in 1 ..=u8:: MAX {
54
- assert_eq ! ( i. checked_ilog2( ) , Some ( ( i as f32 ) . log2( ) as u32 ) , "checking {i}" ) ;
70
+ assert_eq ! (
71
+ i. checked_ilog2( ) ,
72
+ Some ( round_down_imprecise( ( i as f32 ) . log2( ) ) ) ,
73
+ "checking {i}"
74
+ ) ;
55
75
}
56
76
#[ cfg( not( miri) ) ] // Miri is too slow
57
77
for i in 1 ..=u16:: MAX {
58
- // Guard against Android's imprecise f32::ilog2 implementation.
59
- if i != 8192 && i != 32768 {
60
- assert_eq ! ( i. checked_ilog2( ) , Some ( ( i as f32 ) . log2( ) as u32 ) , "checking {i}" ) ;
61
- }
78
+ assert_eq ! (
79
+ i. checked_ilog2( ) ,
80
+ Some ( round_down_imprecise( ( i as f32 ) . log2( ) ) ) ,
81
+ "checking {i}"
82
+ ) ;
62
83
}
63
84
for i in i8:: MIN ..=0 {
64
85
assert_eq ! ( i. checked_ilog2( ) , None , "checking {i}" ) ;
65
86
}
66
87
for i in 1 ..=i8:: MAX {
67
- assert_eq ! ( i. checked_ilog2( ) , Some ( ( i as f32 ) . log2( ) as u32 ) , "checking {i}" ) ;
88
+ assert_eq ! (
89
+ i. checked_ilog2( ) ,
90
+ Some ( round_down_imprecise( ( i as f32 ) . log2( ) ) ) ,
91
+ "checking {i}"
92
+ ) ;
68
93
}
69
94
#[ cfg( not( miri) ) ] // Miri is too slow
70
95
for i in i16:: MIN ..=0 {
71
96
assert_eq ! ( i. checked_ilog2( ) , None , "checking {i}" ) ;
72
97
}
73
98
#[ cfg( not( miri) ) ] // Miri is too slow
74
99
for i in 1 ..=i16:: MAX {
75
- // Guard against Android's imprecise f32::ilog2 implementation.
76
- if i != 8192 {
77
- assert_eq ! ( i. checked_ilog2( ) , Some ( ( i as f32 ) . log2( ) as u32 ) , "checking {i}" ) ;
78
- }
100
+ assert_eq ! (
101
+ i. checked_ilog2( ) ,
102
+ Some ( round_down_imprecise( ( i as f32 ) . log2( ) ) ) ,
103
+ "checking {i}"
104
+ ) ;
79
105
}
80
106
}
81
107
@@ -92,15 +118,27 @@ fn checked_ilog10() {
92
118
}
93
119
#[ cfg( not( miri) ) ] // Miri is too slow
94
120
for i in 1 ..=i16:: MAX {
95
- assert_eq ! ( i. checked_ilog10( ) , Some ( ( i as f32 ) . log10( ) as u32 ) , "checking {i}" ) ;
121
+ assert_eq ! (
122
+ i. checked_ilog10( ) ,
123
+ Some ( round_down_imprecise( ( i as f32 ) . log10( ) ) ) ,
124
+ "checking {i}"
125
+ ) ;
96
126
}
97
127
#[ cfg( not( miri) ) ] // Miri is too slow
98
128
for i in 1 ..=u16:: MAX {
99
- assert_eq ! ( i. checked_ilog10( ) , Some ( ( i as f32 ) . log10( ) as u32 ) , "checking {i}" ) ;
129
+ assert_eq ! (
130
+ i. checked_ilog10( ) ,
131
+ Some ( round_down_imprecise( ( i as f32 ) . log10( ) ) ) ,
132
+ "checking {i}"
133
+ ) ;
100
134
}
101
135
#[ cfg( not( miri) ) ] // Miri is too slow
102
136
for i in 1 ..=100_000u32 {
103
- assert_eq ! ( i. checked_ilog10( ) , Some ( ( i as f32 ) . log10( ) as u32 ) , "checking {i}" ) ;
137
+ assert_eq ! (
138
+ i. checked_ilog10( ) ,
139
+ Some ( round_down_imprecise( ( i as f32 ) . log10( ) ) ) ,
140
+ "checking {i}"
141
+ ) ;
104
142
}
105
143
}
106
144
0 commit comments