11//! Tests for the `Integer::{ilog,log2,log10}` methods.
22
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+
311#[ test]
412fn checked_ilog ( ) {
513 assert_eq ! ( 999u32 . checked_ilog( 10 ) , Some ( 2 ) ) ;
@@ -25,11 +33,19 @@ fn checked_ilog() {
2533 }
2634 #[ cfg( not( miri) ) ] // Miri is too slow
2735 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+ ) ;
2941 }
3042 #[ cfg( not( miri) ) ] // Miri is too slow
3143 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+ ) ;
3349 }
3450}
3551
@@ -46,36 +62,46 @@ fn checked_ilog2() {
4662 assert_eq ! ( 0i8 . checked_ilog2( ) , None ) ;
4763 assert_eq ! ( 0i16 . checked_ilog2( ) , None ) ;
4864
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( ) ) ) ) ;
5268
5369 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+ ) ;
5575 }
5676 #[ cfg( not( miri) ) ] // Miri is too slow
5777 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+ ) ;
6283 }
6384 for i in i8:: MIN ..=0 {
6485 assert_eq ! ( i. checked_ilog2( ) , None , "checking {i}" ) ;
6586 }
6687 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+ ) ;
6893 }
6994 #[ cfg( not( miri) ) ] // Miri is too slow
7095 for i in i16:: MIN ..=0 {
7196 assert_eq ! ( i. checked_ilog2( ) , None , "checking {i}" ) ;
7297 }
7398 #[ cfg( not( miri) ) ] // Miri is too slow
7499 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+ ) ;
79105 }
80106}
81107
@@ -92,15 +118,27 @@ fn checked_ilog10() {
92118 }
93119 #[ cfg( not( miri) ) ] // Miri is too slow
94120 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+ ) ;
96126 }
97127 #[ cfg( not( miri) ) ] // Miri is too slow
98128 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+ ) ;
100134 }
101135 #[ cfg( not( miri) ) ] // Miri is too slow
102136 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+ ) ;
104142 }
105143}
106144
0 commit comments