]> git.lizzy.rs Git - rust.git/blob - library/core/tests/num/int_log.rs
Rollup merge of #103236 - tspiteri:redoc-int-adc-sbb, r=m-ou-se
[rust.git] / library / core / tests / num / int_log.rs
1 //! This tests the `Integer::{ilog,log2,log10}` methods. These tests are in a
2 //! separate file because there's both a large number of them, and not all tests
3 //! can be run on Android. This is because in Android `ilog2` uses an imprecise
4 //! approximation:https://github.com/rust-lang/rust/blob/4825e12fc9c79954aa0fe18f5521efa6c19c7539/src/libstd/sys/unix/android.rs#L27-L53
5
6 #[test]
7 fn checked_ilog() {
8     assert_eq!(999u32.checked_ilog(10), Some(2));
9     assert_eq!(1000u32.checked_ilog(10), Some(3));
10     assert_eq!(555u32.checked_ilog(13), Some(2));
11     assert_eq!(63u32.checked_ilog(4), Some(2));
12     assert_eq!(64u32.checked_ilog(4), Some(3));
13     assert_eq!(10460353203u64.checked_ilog(3), Some(21));
14     assert_eq!(10460353202u64.checked_ilog(3), Some(20));
15     assert_eq!(147808829414345923316083210206383297601u128.checked_ilog(3), Some(80));
16     assert_eq!(147808829414345923316083210206383297600u128.checked_ilog(3), Some(79));
17     assert_eq!(22528399544939174411840147874772641u128.checked_ilog(19683), Some(8));
18     assert_eq!(22528399544939174411840147874772631i128.checked_ilog(19683), Some(7));
19
20     assert_eq!(0u8.checked_ilog(4), None);
21     assert_eq!(0u16.checked_ilog(4), None);
22     assert_eq!(0i8.checked_ilog(4), None);
23     assert_eq!(0i16.checked_ilog(4), None);
24
25     #[cfg(not(miri))] // Miri is too slow
26     for i in i16::MIN..=0 {
27         assert_eq!(i.checked_ilog(4), None);
28     }
29     #[cfg(not(miri))] // Miri is too slow
30     for i in 1..=i16::MAX {
31         assert_eq!(i.checked_ilog(13), Some((i as f32).log(13.0) as u32));
32     }
33     #[cfg(not(miri))] // Miri is too slow
34     for i in 1..=u16::MAX {
35         assert_eq!(i.checked_ilog(13), Some((i as f32).log(13.0) as u32));
36     }
37 }
38
39 #[test]
40 fn checked_ilog2() {
41     assert_eq!(5u32.checked_ilog2(), Some(2));
42     assert_eq!(0u64.checked_ilog2(), None);
43     assert_eq!(128i32.checked_ilog2(), Some(7));
44     assert_eq!((-55i16).checked_ilog2(), None);
45
46     assert_eq!(0u8.checked_ilog2(), None);
47     assert_eq!(0u16.checked_ilog2(), None);
48     assert_eq!(0i8.checked_ilog2(), None);
49     assert_eq!(0i16.checked_ilog2(), None);
50
51     for i in 1..=u8::MAX {
52         assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32));
53     }
54     #[cfg(not(miri))] // Miri is too slow
55     for i in 1..=u16::MAX {
56         // Guard against Android's imprecise f32::ilog2 implementation.
57         if i != 8192 && i != 32768 {
58             assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32));
59         }
60     }
61     for i in i8::MIN..=0 {
62         assert_eq!(i.checked_ilog2(), None);
63     }
64     for i in 1..=i8::MAX {
65         assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32));
66     }
67     #[cfg(not(miri))] // Miri is too slow
68     for i in i16::MIN..=0 {
69         assert_eq!(i.checked_ilog2(), None);
70     }
71     #[cfg(not(miri))] // Miri is too slow
72     for i in 1..=i16::MAX {
73         // Guard against Android's imprecise f32::ilog2 implementation.
74         if i != 8192 {
75             assert_eq!(i.checked_ilog2(), Some((i as f32).log2() as u32));
76         }
77     }
78 }
79
80 // Validate cases that fail on Android's imprecise float ilog2 implementation.
81 #[test]
82 #[cfg(not(target_os = "android"))]
83 fn checked_ilog2_not_android() {
84     assert_eq!(8192u16.checked_ilog2(), Some((8192f32).log2() as u32));
85     assert_eq!(32768u16.checked_ilog2(), Some((32768f32).log2() as u32));
86     assert_eq!(8192i16.checked_ilog2(), Some((8192f32).log2() as u32));
87 }
88
89 #[test]
90 fn checked_ilog10() {
91     assert_eq!(0u8.checked_ilog10(), None);
92     assert_eq!(0u16.checked_ilog10(), None);
93     assert_eq!(0i8.checked_ilog10(), None);
94     assert_eq!(0i16.checked_ilog10(), None);
95
96     #[cfg(not(miri))] // Miri is too slow
97     for i in i16::MIN..=0 {
98         assert_eq!(i.checked_ilog10(), None);
99     }
100     #[cfg(not(miri))] // Miri is too slow
101     for i in 1..=i16::MAX {
102         assert_eq!(i.checked_ilog10(), Some((i as f32).log10() as u32));
103     }
104     #[cfg(not(miri))] // Miri is too slow
105     for i in 1..=u16::MAX {
106         assert_eq!(i.checked_ilog10(), Some((i as f32).log10() as u32));
107     }
108     #[cfg(not(miri))] // Miri is too slow
109     for i in 1..=100_000u32 {
110         assert_eq!(i.checked_ilog10(), Some((i as f32).log10() as u32));
111     }
112 }
113
114 macro_rules! ilog10_loop {
115     ($T:ty, $ilog10_max:expr) => {
116         assert_eq!(<$T>::MAX.ilog10(), $ilog10_max);
117         for i in 0..=$ilog10_max {
118             let p = (10 as $T).pow(i as u32);
119             if p >= 10 {
120                 assert_eq!((p - 9).ilog10(), i - 1);
121                 assert_eq!((p - 1).ilog10(), i - 1);
122             }
123             assert_eq!(p.ilog10(), i);
124             assert_eq!((p + 1).ilog10(), i);
125             if p >= 10 {
126                 assert_eq!((p + 9).ilog10(), i);
127             }
128
129             // also check `x.ilog(10)`
130             if p >= 10 {
131                 assert_eq!((p - 9).ilog(10), i - 1);
132                 assert_eq!((p - 1).ilog(10), i - 1);
133             }
134             assert_eq!(p.ilog(10), i);
135             assert_eq!((p + 1).ilog(10), i);
136             if p >= 10 {
137                 assert_eq!((p + 9).ilog(10), i);
138             }
139         }
140     };
141 }
142
143 #[test]
144 fn ilog10_u8() {
145     ilog10_loop! { u8, 2 }
146 }
147
148 #[test]
149 fn ilog10_u16() {
150     ilog10_loop! { u16, 4 }
151 }
152
153 #[test]
154 fn ilog10_u32() {
155     ilog10_loop! { u32, 9 }
156 }
157
158 #[test]
159 fn ilog10_u64() {
160     ilog10_loop! { u64, 19 }
161 }
162
163 #[test]
164 fn ilog10_u128() {
165     ilog10_loop! { u128, 38 }
166 }
167
168 #[test]
169 #[should_panic(expected = "argument of integer logarithm must be positive")]
170 fn ilog2_of_0_panic() {
171     let _ = 0u32.ilog2();
172 }
173
174 #[test]
175 #[should_panic(expected = "argument of integer logarithm must be positive")]
176 fn ilog10_of_0_panic() {
177     let _ = 0u32.ilog10();
178 }
179
180 #[test]
181 #[should_panic(expected = "argument of integer logarithm must be positive")]
182 fn ilog3_of_0_panic() {
183     let _ = 0u32.ilog(3);
184 }
185
186 #[test]
187 #[should_panic(expected = "base of integer logarithm must be at least 2")]
188 fn ilog0_of_1_panic() {
189     let _ = 1u32.ilog(0);
190 }
191
192 #[test]
193 #[should_panic(expected = "base of integer logarithm must be at least 2")]
194 fn ilog1_of_1_panic() {
195     let _ = 1u32.ilog(1);
196 }