]> git.lizzy.rs Git - rust.git/blob - src/libcore/tests/num/mod.rs
Auto merge of #42612 - est31:master, r=nagisa
[rust.git] / src / libcore / tests / num / mod.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use core::convert::TryFrom;
12 use core::cmp::PartialEq;
13 use core::fmt::Debug;
14 use core::marker::Copy;
15 use core::ops::{Add, Sub, Mul, Div, Rem};
16 use core::option::Option;
17 use core::option::Option::{Some, None};
18
19 #[macro_use]
20 mod int_macros;
21
22 mod i8;
23 mod i16;
24 mod i32;
25 mod i64;
26
27 #[macro_use]
28 mod uint_macros;
29
30 mod u8;
31 mod u16;
32 mod u32;
33 mod u64;
34
35 mod flt2dec;
36 mod dec2flt;
37 mod bignum;
38
39 /// Helper function for testing numeric operations
40 pub fn test_num<T>(ten: T, two: T) where
41     T: PartialEq
42      + Add<Output=T> + Sub<Output=T>
43      + Mul<Output=T> + Div<Output=T>
44      + Rem<Output=T> + Debug
45      + Copy
46 {
47     assert_eq!(ten.add(two),  ten + two);
48     assert_eq!(ten.sub(two),  ten - two);
49     assert_eq!(ten.mul(two),  ten * two);
50     assert_eq!(ten.div(two),  ten / two);
51     assert_eq!(ten.rem(two),  ten % two);
52 }
53
54 #[test]
55 fn from_str_issue7588() {
56     let u : Option<u8> = u8::from_str_radix("1000", 10).ok();
57     assert_eq!(u, None);
58     let s : Option<i16> = i16::from_str_radix("80000", 10).ok();
59     assert_eq!(s, None);
60 }
61
62 #[test]
63 fn test_int_from_str_overflow() {
64     let mut i8_val: i8 = 127;
65     assert_eq!("127".parse::<i8>().ok(), Some(i8_val));
66     assert_eq!("128".parse::<i8>().ok(), None);
67
68     i8_val = i8_val.wrapping_add(1);
69     assert_eq!("-128".parse::<i8>().ok(), Some(i8_val));
70     assert_eq!("-129".parse::<i8>().ok(), None);
71
72     let mut i16_val: i16 = 32_767;
73     assert_eq!("32767".parse::<i16>().ok(), Some(i16_val));
74     assert_eq!("32768".parse::<i16>().ok(), None);
75
76     i16_val = i16_val.wrapping_add(1);
77     assert_eq!("-32768".parse::<i16>().ok(), Some(i16_val));
78     assert_eq!("-32769".parse::<i16>().ok(), None);
79
80     let mut i32_val: i32 = 2_147_483_647;
81     assert_eq!("2147483647".parse::<i32>().ok(), Some(i32_val));
82     assert_eq!("2147483648".parse::<i32>().ok(), None);
83
84     i32_val = i32_val.wrapping_add(1);
85     assert_eq!("-2147483648".parse::<i32>().ok(), Some(i32_val));
86     assert_eq!("-2147483649".parse::<i32>().ok(), None);
87
88     let mut i64_val: i64 = 9_223_372_036_854_775_807;
89     assert_eq!("9223372036854775807".parse::<i64>().ok(), Some(i64_val));
90     assert_eq!("9223372036854775808".parse::<i64>().ok(), None);
91
92     i64_val = i64_val.wrapping_add(1);
93     assert_eq!("-9223372036854775808".parse::<i64>().ok(), Some(i64_val));
94     assert_eq!("-9223372036854775809".parse::<i64>().ok(), None);
95 }
96
97 #[test]
98 fn test_leading_plus() {
99     assert_eq!("+127".parse::<u8>().ok(), Some(127));
100     assert_eq!("+9223372036854775807".parse::<i64>().ok(), Some(9223372036854775807));
101 }
102
103 #[test]
104 fn test_invalid() {
105     assert_eq!("--129".parse::<i8>().ok(), None);
106     assert_eq!("++129".parse::<i8>().ok(), None);
107     assert_eq!("Съешь".parse::<u8>().ok(), None);
108 }
109
110 #[test]
111 fn test_empty() {
112     assert_eq!("-".parse::<i8>().ok(), None);
113     assert_eq!("+".parse::<i8>().ok(), None);
114     assert_eq!("".parse::<u8>().ok(), None);
115 }
116
117 macro_rules! test_impl_from {
118     ($fn_name: ident, $Small: ty, $Large: ty) => {
119         #[test]
120         fn $fn_name() {
121             let small_max = <$Small>::max_value();
122             let small_min = <$Small>::min_value();
123             let large_max: $Large = small_max.into();
124             let large_min: $Large = small_min.into();
125             assert_eq!(large_max as $Small, small_max);
126             assert_eq!(large_min as $Small, small_min);
127         }
128     }
129 }
130
131 // Unsigned -> Unsigned
132 test_impl_from! { test_u8u16, u8, u16 }
133 test_impl_from! { test_u8u32, u8, u32 }
134 test_impl_from! { test_u8u64, u8, u64 }
135 test_impl_from! { test_u8usize, u8, usize }
136 test_impl_from! { test_u16u32, u16, u32 }
137 test_impl_from! { test_u16u64, u16, u64 }
138 test_impl_from! { test_u32u64, u32, u64 }
139
140 // Signed -> Signed
141 test_impl_from! { test_i8i16, i8, i16 }
142 test_impl_from! { test_i8i32, i8, i32 }
143 test_impl_from! { test_i8i64, i8, i64 }
144 test_impl_from! { test_i8isize, i8, isize }
145 test_impl_from! { test_i16i32, i16, i32 }
146 test_impl_from! { test_i16i64, i16, i64 }
147 test_impl_from! { test_i32i64, i32, i64 }
148
149 // Unsigned -> Signed
150 test_impl_from! { test_u8i16, u8, i16 }
151 test_impl_from! { test_u8i32, u8, i32 }
152 test_impl_from! { test_u8i64, u8, i64 }
153 test_impl_from! { test_u16i32, u16, i32 }
154 test_impl_from! { test_u16i64, u16, i64 }
155 test_impl_from! { test_u32i64, u32, i64 }
156
157 // Signed -> Float
158 test_impl_from! { test_i8f32, i8, f32 }
159 test_impl_from! { test_i8f64, i8, f64 }
160 test_impl_from! { test_i16f32, i16, f32 }
161 test_impl_from! { test_i16f64, i16, f64 }
162 test_impl_from! { test_i32f64, i32, f64 }
163
164 // Unsigned -> Float
165 test_impl_from! { test_u8f32, u8, f32 }
166 test_impl_from! { test_u8f64, u8, f64 }
167 test_impl_from! { test_u16f32, u16, f32 }
168 test_impl_from! { test_u16f64, u16, f64 }
169 test_impl_from! { test_u32f64, u32, f64 }
170
171 // Float -> Float
172 #[cfg_attr(all(target_arch = "wasm32", target_os = "emscripten"), ignore)] // issue 42630
173 #[test]
174 fn test_f32f64() {
175     use core::f32;
176
177     let max: f64 = f32::MAX.into();
178     assert_eq!(max as f32, f32::MAX);
179     assert!(max.is_normal());
180
181     let min: f64 = f32::MIN.into();
182     assert_eq!(min as f32, f32::MIN);
183     assert!(min.is_normal());
184
185     let min_positive: f64 = f32::MIN_POSITIVE.into();
186     assert_eq!(min_positive as f32, f32::MIN_POSITIVE);
187     assert!(min_positive.is_normal());
188
189     let epsilon: f64 = f32::EPSILON.into();
190     assert_eq!(epsilon as f32, f32::EPSILON);
191     assert!(epsilon.is_normal());
192
193     let zero: f64 = (0.0f32).into();
194     assert_eq!(zero as f32, 0.0f32);
195     assert!(zero.is_sign_positive());
196
197     let neg_zero: f64 = (-0.0f32).into();
198     assert_eq!(neg_zero as f32, -0.0f32);
199     assert!(neg_zero.is_sign_negative());
200
201     let infinity: f64 = f32::INFINITY.into();
202     assert_eq!(infinity as f32, f32::INFINITY);
203     assert!(infinity.is_infinite());
204     assert!(infinity.is_sign_positive());
205
206     let neg_infinity: f64 = f32::NEG_INFINITY.into();
207     assert_eq!(neg_infinity as f32, f32::NEG_INFINITY);
208     assert!(neg_infinity.is_infinite());
209     assert!(neg_infinity.is_sign_negative());
210
211     let nan: f64 = f32::NAN.into();
212     assert!(nan.is_nan());
213 }
214
215 macro_rules! test_impl_try_from_always_ok {
216     ($fn_name:ident, $source:ty, $target: ty) => {
217         #[test]
218         fn $fn_name() {
219             let max = <$source>::max_value();
220             let min = <$source>::min_value();
221             let zero: $source = 0;
222             assert_eq!(<$target as TryFrom<$source>>::try_from(max).unwrap(),
223                        max as $target);
224             assert_eq!(<$target as TryFrom<$source>>::try_from(min).unwrap(),
225                        min as $target);
226             assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
227                        zero as $target);
228         }
229     }
230 }
231
232 test_impl_try_from_always_ok! { test_try_u8u8, u8, u8 }
233 test_impl_try_from_always_ok! { test_try_u8u16, u8, u16 }
234 test_impl_try_from_always_ok! { test_try_u8u32, u8, u32 }
235 test_impl_try_from_always_ok! { test_try_u8u64, u8, u64 }
236 test_impl_try_from_always_ok! { test_try_u8i16, u8, i16 }
237 test_impl_try_from_always_ok! { test_try_u8i32, u8, i32 }
238 test_impl_try_from_always_ok! { test_try_u8i64, u8, i64 }
239
240 test_impl_try_from_always_ok! { test_try_u16u16, u16, u16 }
241 test_impl_try_from_always_ok! { test_try_u16u32, u16, u32 }
242 test_impl_try_from_always_ok! { test_try_u16u64, u16, u64 }
243 test_impl_try_from_always_ok! { test_try_u16i32, u16, i32 }
244 test_impl_try_from_always_ok! { test_try_u16i64, u16, i64 }
245
246 test_impl_try_from_always_ok! { test_try_u32u32, u32, u32 }
247 test_impl_try_from_always_ok! { test_try_u32u64, u32, u64 }
248 test_impl_try_from_always_ok! { test_try_u32i64, u32, i64 }
249
250 test_impl_try_from_always_ok! { test_try_u64u64, u64, u64 }
251
252 test_impl_try_from_always_ok! { test_try_i8i8, i8, i8 }
253 test_impl_try_from_always_ok! { test_try_i8i16, i8, i16 }
254 test_impl_try_from_always_ok! { test_try_i8i32, i8, i32 }
255 test_impl_try_from_always_ok! { test_try_i8i64, i8, i64 }
256
257 test_impl_try_from_always_ok! { test_try_i16i16, i16, i16 }
258 test_impl_try_from_always_ok! { test_try_i16i32, i16, i32 }
259 test_impl_try_from_always_ok! { test_try_i16i64, i16, i64 }
260
261 test_impl_try_from_always_ok! { test_try_i32i32, i32, i32 }
262 test_impl_try_from_always_ok! { test_try_i32i64, i32, i64 }
263
264 test_impl_try_from_always_ok! { test_try_i64i64, i64, i64 }
265
266 macro_rules! test_impl_try_from_signed_to_unsigned_upper_ok {
267     ($fn_name:ident, $source:ty, $target:ty) => {
268         #[test]
269         fn $fn_name() {
270             let max = <$source>::max_value();
271             let min = <$source>::min_value();
272             let zero: $source = 0;
273             let neg_one: $source = -1;
274             assert_eq!(<$target as TryFrom<$source>>::try_from(max).unwrap(),
275                        max as $target);
276             assert!(<$target as TryFrom<$source>>::try_from(min).is_err());
277             assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
278                        zero as $target);
279             assert!(<$target as TryFrom<$source>>::try_from(neg_one).is_err());
280         }
281     }
282 }
283
284 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u8, i8, u8 }
285 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u16, i8, u16 }
286 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u32, i8, u32 }
287 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u64, i8, u64 }
288
289 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u16, i16, u16 }
290 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u32, i16, u32 }
291 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u64, i16, u64 }
292
293 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32u32, i32, u32 }
294 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32u64, i32, u64 }
295
296 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i64u64, i64, u64 }
297
298 macro_rules! test_impl_try_from_unsigned_to_signed_upper_err {
299     ($fn_name:ident, $source:ty, $target:ty) => {
300         #[test]
301         fn $fn_name() {
302             let max = <$source>::max_value();
303             let min = <$source>::min_value();
304             let zero: $source = 0;
305             assert!(<$target as TryFrom<$source>>::try_from(max).is_err());
306             assert_eq!(<$target as TryFrom<$source>>::try_from(min).unwrap(),
307                        min as $target);
308             assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
309                        zero as $target);
310         }
311     }
312 }
313
314 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u8i8, u8, i8 }
315
316 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u16i8, u16, i8 }
317 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u16i16, u16, i16 }
318
319 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32i8, u32, i8 }
320 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32i16, u32, i16 }
321 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32i32, u32, i32 }
322
323 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i8, u64, i8 }
324 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i16, u64, i16 }
325 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i32, u64, i32 }
326 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i64, u64, i64 }
327
328 macro_rules! test_impl_try_from_same_sign_err {
329     ($fn_name:ident, $source:ty, $target:ty) => {
330         #[test]
331         fn $fn_name() {
332             let max = <$source>::max_value();
333             let min = <$source>::min_value();
334             let zero: $source = 0;
335             let t_max = <$target>::max_value();
336             let t_min = <$target>::min_value();
337             assert!(<$target as TryFrom<$source>>::try_from(max).is_err());
338             if min != 0 {
339                 assert!(<$target as TryFrom<$source>>::try_from(min).is_err());
340             }
341             assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
342                        zero as $target);
343             assert_eq!(<$target as TryFrom<$source>>::try_from(t_max as $source)
344                             .unwrap(),
345                        t_max as $target);
346             assert_eq!(<$target as TryFrom<$source>>::try_from(t_min as $source)
347                             .unwrap(),
348                        t_min as $target);
349         }
350     }
351 }
352
353 test_impl_try_from_same_sign_err! { test_try_u16u8, u16, u8 }
354
355 test_impl_try_from_same_sign_err! { test_try_u32u8, u32, u8 }
356 test_impl_try_from_same_sign_err! { test_try_u32u16, u32, u16 }
357
358 test_impl_try_from_same_sign_err! { test_try_u64u8, u64, u8 }
359 test_impl_try_from_same_sign_err! { test_try_u64u16, u64, u16 }
360 test_impl_try_from_same_sign_err! { test_try_u64u32, u64, u32 }
361
362 test_impl_try_from_same_sign_err! { test_try_i16i8, i16, i8 }
363
364 test_impl_try_from_same_sign_err! { test_try_i32i8, i32, i8 }
365 test_impl_try_from_same_sign_err! { test_try_i32i16, i32, i16 }
366
367 test_impl_try_from_same_sign_err! { test_try_i64i8, i64, i8 }
368 test_impl_try_from_same_sign_err! { test_try_i64i16, i64, i16 }
369 test_impl_try_from_same_sign_err! { test_try_i64i32, i64, i32 }
370
371 macro_rules! test_impl_try_from_signed_to_unsigned_err {
372     ($fn_name:ident, $source:ty, $target:ty) => {
373         #[test]
374         fn $fn_name() {
375             let max = <$source>::max_value();
376             let min = <$source>::min_value();
377             let zero: $source = 0;
378             let t_max = <$target>::max_value();
379             let t_min = <$target>::min_value();
380             assert!(<$target as TryFrom<$source>>::try_from(max).is_err());
381             assert!(<$target as TryFrom<$source>>::try_from(min).is_err());
382             assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
383                        zero as $target);
384             assert_eq!(<$target as TryFrom<$source>>::try_from(t_max as $source)
385                             .unwrap(),
386                        t_max as $target);
387             assert_eq!(<$target as TryFrom<$source>>::try_from(t_min as $source)
388                             .unwrap(),
389                        t_min as $target);
390         }
391     }
392 }
393
394 test_impl_try_from_signed_to_unsigned_err! { test_try_i16u8, i16, u8 }
395
396 test_impl_try_from_signed_to_unsigned_err! { test_try_i32u8, i32, u8 }
397 test_impl_try_from_signed_to_unsigned_err! { test_try_i32u16, i32, u16 }
398
399 test_impl_try_from_signed_to_unsigned_err! { test_try_i64u8, i64, u8 }
400 test_impl_try_from_signed_to_unsigned_err! { test_try_i64u16, i64, u16 }
401 test_impl_try_from_signed_to_unsigned_err! { test_try_i64u32, i64, u32 }