]> git.lizzy.rs Git - rust.git/blob - src/libcore/tests/num/mod.rs
Auto merge of #40996 - alexcrichton:update-cargo, r=alexcrichton
[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 #[test]
173 fn test_f32f64() {
174     use core::f32;
175
176     let max: f64 = f32::MAX.into();
177     assert_eq!(max as f32, f32::MAX);
178     assert!(max.is_normal());
179
180     let min: f64 = f32::MIN.into();
181     assert_eq!(min as f32, f32::MIN);
182     assert!(min.is_normal());
183
184     let min_positive: f64 = f32::MIN_POSITIVE.into();
185     assert_eq!(min_positive as f32, f32::MIN_POSITIVE);
186     assert!(min_positive.is_normal());
187
188     let epsilon: f64 = f32::EPSILON.into();
189     assert_eq!(epsilon as f32, f32::EPSILON);
190     assert!(epsilon.is_normal());
191
192     let zero: f64 = (0.0f32).into();
193     assert_eq!(zero as f32, 0.0f32);
194     assert!(zero.is_sign_positive());
195
196     let neg_zero: f64 = (-0.0f32).into();
197     assert_eq!(neg_zero as f32, -0.0f32);
198     assert!(neg_zero.is_sign_negative());
199
200     let infinity: f64 = f32::INFINITY.into();
201     assert_eq!(infinity as f32, f32::INFINITY);
202     assert!(infinity.is_infinite());
203     assert!(infinity.is_sign_positive());
204
205     let neg_infinity: f64 = f32::NEG_INFINITY.into();
206     assert_eq!(neg_infinity as f32, f32::NEG_INFINITY);
207     assert!(neg_infinity.is_infinite());
208     assert!(neg_infinity.is_sign_negative());
209
210     let nan: f64 = f32::NAN.into();
211     assert!(nan.is_nan());
212 }
213
214 macro_rules! test_impl_try_from_always_ok {
215     ($fn_name:ident, $source:ty, $target: ty) => {
216         #[test]
217         fn $fn_name() {
218             let max = <$source>::max_value();
219             let min = <$source>::min_value();
220             let zero: $source = 0;
221             assert_eq!(<$target as TryFrom<$source>>::try_from(max).unwrap(),
222                        max as $target);
223             assert_eq!(<$target as TryFrom<$source>>::try_from(min).unwrap(),
224                        min as $target);
225             assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
226                        zero as $target);
227         }
228     }
229 }
230
231 test_impl_try_from_always_ok! { test_try_u8u8, u8, u8 }
232 test_impl_try_from_always_ok! { test_try_u8u16, u8, u16 }
233 test_impl_try_from_always_ok! { test_try_u8u32, u8, u32 }
234 test_impl_try_from_always_ok! { test_try_u8u64, u8, u64 }
235 test_impl_try_from_always_ok! { test_try_u8i16, u8, i16 }
236 test_impl_try_from_always_ok! { test_try_u8i32, u8, i32 }
237 test_impl_try_from_always_ok! { test_try_u8i64, u8, i64 }
238
239 test_impl_try_from_always_ok! { test_try_u16u16, u16, u16 }
240 test_impl_try_from_always_ok! { test_try_u16u32, u16, u32 }
241 test_impl_try_from_always_ok! { test_try_u16u64, u16, u64 }
242 test_impl_try_from_always_ok! { test_try_u16i32, u16, i32 }
243 test_impl_try_from_always_ok! { test_try_u16i64, u16, i64 }
244
245 test_impl_try_from_always_ok! { test_try_u32u32, u32, u32 }
246 test_impl_try_from_always_ok! { test_try_u32u64, u32, u64 }
247 test_impl_try_from_always_ok! { test_try_u32i64, u32, i64 }
248
249 test_impl_try_from_always_ok! { test_try_u64u64, u64, u64 }
250
251 test_impl_try_from_always_ok! { test_try_i8i8, i8, i8 }
252 test_impl_try_from_always_ok! { test_try_i8i16, i8, i16 }
253 test_impl_try_from_always_ok! { test_try_i8i32, i8, i32 }
254 test_impl_try_from_always_ok! { test_try_i8i64, i8, i64 }
255
256 test_impl_try_from_always_ok! { test_try_i16i16, i16, i16 }
257 test_impl_try_from_always_ok! { test_try_i16i32, i16, i32 }
258 test_impl_try_from_always_ok! { test_try_i16i64, i16, i64 }
259
260 test_impl_try_from_always_ok! { test_try_i32i32, i32, i32 }
261 test_impl_try_from_always_ok! { test_try_i32i64, i32, i64 }
262
263 test_impl_try_from_always_ok! { test_try_i64i64, i64, i64 }
264
265 macro_rules! test_impl_try_from_signed_to_unsigned_upper_ok {
266     ($fn_name:ident, $source:ty, $target:ty) => {
267         #[test]
268         fn $fn_name() {
269             let max = <$source>::max_value();
270             let min = <$source>::min_value();
271             let zero: $source = 0;
272             let neg_one: $source = -1;
273             assert_eq!(<$target as TryFrom<$source>>::try_from(max).unwrap(),
274                        max as $target);
275             assert!(<$target as TryFrom<$source>>::try_from(min).is_err());
276             assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
277                        zero as $target);
278             assert!(<$target as TryFrom<$source>>::try_from(neg_one).is_err());
279         }
280     }
281 }
282
283 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u8, i8, u8 }
284 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u16, i8, u16 }
285 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u32, i8, u32 }
286 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i8u64, i8, u64 }
287
288 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u16, i16, u16 }
289 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u32, i16, u32 }
290 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i16u64, i16, u64 }
291
292 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32u32, i32, u32 }
293 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i32u64, i32, u64 }
294
295 test_impl_try_from_signed_to_unsigned_upper_ok! { test_try_i64u64, i64, u64 }
296
297 macro_rules! test_impl_try_from_unsigned_to_signed_upper_err {
298     ($fn_name:ident, $source:ty, $target:ty) => {
299         #[test]
300         fn $fn_name() {
301             let max = <$source>::max_value();
302             let min = <$source>::min_value();
303             let zero: $source = 0;
304             assert!(<$target as TryFrom<$source>>::try_from(max).is_err());
305             assert_eq!(<$target as TryFrom<$source>>::try_from(min).unwrap(),
306                        min as $target);
307             assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
308                        zero as $target);
309         }
310     }
311 }
312
313 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u8i8, u8, i8 }
314
315 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u16i8, u16, i8 }
316 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u16i16, u16, i16 }
317
318 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32i8, u32, i8 }
319 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32i16, u32, i16 }
320 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u32i32, u32, i32 }
321
322 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i8, u64, i8 }
323 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i16, u64, i16 }
324 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i32, u64, i32 }
325 test_impl_try_from_unsigned_to_signed_upper_err! { test_try_u64i64, u64, i64 }
326
327 macro_rules! test_impl_try_from_same_sign_err {
328     ($fn_name:ident, $source:ty, $target:ty) => {
329         #[test]
330         fn $fn_name() {
331             let max = <$source>::max_value();
332             let min = <$source>::min_value();
333             let zero: $source = 0;
334             let t_max = <$target>::max_value();
335             let t_min = <$target>::min_value();
336             assert!(<$target as TryFrom<$source>>::try_from(max).is_err());
337             if min != 0 {
338                 assert!(<$target as TryFrom<$source>>::try_from(min).is_err());
339             }
340             assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
341                        zero as $target);
342             assert_eq!(<$target as TryFrom<$source>>::try_from(t_max as $source)
343                             .unwrap(),
344                        t_max as $target);
345             assert_eq!(<$target as TryFrom<$source>>::try_from(t_min as $source)
346                             .unwrap(),
347                        t_min as $target);
348         }
349     }
350 }
351
352 test_impl_try_from_same_sign_err! { test_try_u16u8, u16, u8 }
353
354 test_impl_try_from_same_sign_err! { test_try_u32u8, u32, u8 }
355 test_impl_try_from_same_sign_err! { test_try_u32u16, u32, u16 }
356
357 test_impl_try_from_same_sign_err! { test_try_u64u8, u64, u8 }
358 test_impl_try_from_same_sign_err! { test_try_u64u16, u64, u16 }
359 test_impl_try_from_same_sign_err! { test_try_u64u32, u64, u32 }
360
361 test_impl_try_from_same_sign_err! { test_try_i16i8, i16, i8 }
362
363 test_impl_try_from_same_sign_err! { test_try_i32i8, i32, i8 }
364 test_impl_try_from_same_sign_err! { test_try_i32i16, i32, i16 }
365
366 test_impl_try_from_same_sign_err! { test_try_i64i8, i64, i8 }
367 test_impl_try_from_same_sign_err! { test_try_i64i16, i64, i16 }
368 test_impl_try_from_same_sign_err! { test_try_i64i32, i64, i32 }
369
370 macro_rules! test_impl_try_from_signed_to_unsigned_err {
371     ($fn_name:ident, $source:ty, $target:ty) => {
372         #[test]
373         fn $fn_name() {
374             let max = <$source>::max_value();
375             let min = <$source>::min_value();
376             let zero: $source = 0;
377             let t_max = <$target>::max_value();
378             let t_min = <$target>::min_value();
379             assert!(<$target as TryFrom<$source>>::try_from(max).is_err());
380             assert!(<$target as TryFrom<$source>>::try_from(min).is_err());
381             assert_eq!(<$target as TryFrom<$source>>::try_from(zero).unwrap(),
382                        zero as $target);
383             assert_eq!(<$target as TryFrom<$source>>::try_from(t_max as $source)
384                             .unwrap(),
385                        t_max as $target);
386             assert_eq!(<$target as TryFrom<$source>>::try_from(t_min as $source)
387                             .unwrap(),
388                        t_min as $target);
389         }
390     }
391 }
392
393 test_impl_try_from_signed_to_unsigned_err! { test_try_i16u8, i16, u8 }
394
395 test_impl_try_from_signed_to_unsigned_err! { test_try_i32u8, i32, u8 }
396 test_impl_try_from_signed_to_unsigned_err! { test_try_i32u16, i32, u16 }
397
398 test_impl_try_from_signed_to_unsigned_err! { test_try_i64u8, i64, u8 }
399 test_impl_try_from_signed_to_unsigned_err! { test_try_i64u16, i64, u16 }
400 test_impl_try_from_signed_to_unsigned_err! { test_try_i64u32, i64, u32 }