]> git.lizzy.rs Git - rust.git/blob - src/libstd/num/mod.rs
Merge pull request #20510 from tshepang/patch-6
[rust.git] / src / libstd / num / mod.rs
1 // Copyright 2012-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 //! Numeric traits and functions for generic mathematics
12 //!
13 //! These are implemented for the primitive numeric types in `std::{u8, u16,
14 //! u32, u64, uint, i8, i16, i32, i64, int, f32, f64}`.
15
16 #![stable]
17 #![allow(missing_docs)]
18
19 #[cfg(test)] use cmp::PartialEq;
20 #[cfg(test)] use fmt::Show;
21 #[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem};
22 #[cfg(test)] use kinds::Copy;
23
24 pub use core::num::{Int, SignedInt, UnsignedInt};
25 pub use core::num::{cast, FromPrimitive, NumCast, ToPrimitive};
26 pub use core::num::{from_int, from_i8, from_i16, from_i32, from_i64};
27 pub use core::num::{from_uint, from_u8, from_u16, from_u32, from_u64};
28 pub use core::num::{from_f32, from_f64};
29 pub use core::num::{FromStrRadix, from_str_radix};
30 pub use core::num::{FpCategory, Float};
31
32 #[experimental = "may be removed or relocated"]
33 pub mod strconv;
34
35 /// Mathematical operations on primitive floating point numbers.
36 #[unstable = "may be altered to inline the Float trait"]
37 pub trait FloatMath: Float {
38     /// Constructs a floating point number created by multiplying `x` by 2
39     /// raised to the power of `exp`.
40     fn ldexp(x: Self, exp: int) -> Self;
41     /// Breaks the number into a normalized fraction and a base-2 exponent,
42     /// satisfying:
43     ///
44     ///  * `self = x * pow(2, exp)`
45     ///
46     ///  * `0.5 <= abs(x) < 1.0`
47     fn frexp(self) -> (Self, int);
48
49     /// Returns the next representable floating-point value in the direction of
50     /// `other`.
51     fn next_after(self, other: Self) -> Self;
52
53     /// Returns the maximum of the two numbers.
54     fn max(self, other: Self) -> Self;
55     /// Returns the minimum of the two numbers.
56     fn min(self, other: Self) -> Self;
57
58     /// The positive difference of two numbers. Returns `0.0` if the number is
59     /// less than or equal to `other`, otherwise the difference between`self`
60     /// and `other` is returned.
61     fn abs_sub(self, other: Self) -> Self;
62
63     /// Take the cubic root of a number.
64     fn cbrt(self) -> Self;
65     /// Calculate the length of the hypotenuse of a right-angle triangle given
66     /// legs of length `x` and `y`.
67     fn hypot(self, other: Self) -> Self;
68
69     /// Computes the sine of a number (in radians).
70     fn sin(self) -> Self;
71     /// Computes the cosine of a number (in radians).
72     fn cos(self) -> Self;
73     /// Computes the tangent of a number (in radians).
74     fn tan(self) -> Self;
75
76     /// Computes the arcsine of a number. Return value is in radians in
77     /// the range [-pi/2, pi/2] or NaN if the number is outside the range
78     /// [-1, 1].
79     fn asin(self) -> Self;
80     /// Computes the arccosine of a number. Return value is in radians in
81     /// the range [0, pi] or NaN if the number is outside the range
82     /// [-1, 1].
83     fn acos(self) -> Self;
84     /// Computes the arctangent of a number. Return value is in radians in the
85     /// range [-pi/2, pi/2];
86     fn atan(self) -> Self;
87     /// Computes the four quadrant arctangent of a number, `y`, and another
88     /// number `x`. Return value is in radians in the range [-pi, pi].
89     fn atan2(self, other: Self) -> Self;
90     /// Simultaneously computes the sine and cosine of the number, `x`. Returns
91     /// `(sin(x), cos(x))`.
92     fn sin_cos(self) -> (Self, Self);
93
94     /// Returns the exponential of the number, minus 1, in a way that is
95     /// accurate even if the number is close to zero.
96     fn exp_m1(self) -> Self;
97     /// Returns the natural logarithm of the number plus 1 (`ln(1+n)`) more
98     /// accurately than if the operations were performed separately.
99     fn ln_1p(self) -> Self;
100
101     /// Hyperbolic sine function.
102     fn sinh(self) -> Self;
103     /// Hyperbolic cosine function.
104     fn cosh(self) -> Self;
105     /// Hyperbolic tangent function.
106     fn tanh(self) -> Self;
107     /// Inverse hyperbolic sine function.
108     fn asinh(self) -> Self;
109     /// Inverse hyperbolic cosine function.
110     fn acosh(self) -> Self;
111     /// Inverse hyperbolic tangent function.
112     fn atanh(self) -> Self;
113 }
114
115 // DEPRECATED
116
117 /// Helper function for testing numeric operations
118 #[cfg(test)]
119 pub fn test_num<T>(ten: T, two: T) where
120     T: PartialEq + NumCast
121      + Add<Output=T> + Sub<Output=T>
122      + Mul<Output=T> + Div<Output=T>
123      + Rem<Output=T> + Show
124      + Copy
125 {
126     assert_eq!(ten.add(two),  cast(12i).unwrap());
127     assert_eq!(ten.sub(two),  cast(8i).unwrap());
128     assert_eq!(ten.mul(two),  cast(20i).unwrap());
129     assert_eq!(ten.div(two),  cast(5i).unwrap());
130     assert_eq!(ten.rem(two),  cast(0i).unwrap());
131
132     assert_eq!(ten.add(two),  ten + two);
133     assert_eq!(ten.sub(two),  ten - two);
134     assert_eq!(ten.mul(two),  ten * two);
135     assert_eq!(ten.div(two),  ten / two);
136     assert_eq!(ten.rem(two),  ten % two);
137 }
138
139 #[cfg(test)]
140 mod tests {
141     use prelude::v1::*;
142     use super::*;
143     use i8;
144     use i16;
145     use i32;
146     use i64;
147     use int;
148     use u8;
149     use u16;
150     use u32;
151     use u64;
152     use uint;
153
154     macro_rules! test_cast_20 {
155         ($_20:expr) => ({
156             let _20 = $_20;
157
158             assert_eq!(20u,   _20.to_uint().unwrap());
159             assert_eq!(20u8,  _20.to_u8().unwrap());
160             assert_eq!(20u16, _20.to_u16().unwrap());
161             assert_eq!(20u32, _20.to_u32().unwrap());
162             assert_eq!(20u64, _20.to_u64().unwrap());
163             assert_eq!(20i,   _20.to_int().unwrap());
164             assert_eq!(20i8,  _20.to_i8().unwrap());
165             assert_eq!(20i16, _20.to_i16().unwrap());
166             assert_eq!(20i32, _20.to_i32().unwrap());
167             assert_eq!(20i64, _20.to_i64().unwrap());
168             assert_eq!(20f32, _20.to_f32().unwrap());
169             assert_eq!(20f64, _20.to_f64().unwrap());
170
171             assert_eq!(_20, NumCast::from(20u).unwrap());
172             assert_eq!(_20, NumCast::from(20u8).unwrap());
173             assert_eq!(_20, NumCast::from(20u16).unwrap());
174             assert_eq!(_20, NumCast::from(20u32).unwrap());
175             assert_eq!(_20, NumCast::from(20u64).unwrap());
176             assert_eq!(_20, NumCast::from(20i).unwrap());
177             assert_eq!(_20, NumCast::from(20i8).unwrap());
178             assert_eq!(_20, NumCast::from(20i16).unwrap());
179             assert_eq!(_20, NumCast::from(20i32).unwrap());
180             assert_eq!(_20, NumCast::from(20i64).unwrap());
181             assert_eq!(_20, NumCast::from(20f32).unwrap());
182             assert_eq!(_20, NumCast::from(20f64).unwrap());
183
184             assert_eq!(_20, cast(20u).unwrap());
185             assert_eq!(_20, cast(20u8).unwrap());
186             assert_eq!(_20, cast(20u16).unwrap());
187             assert_eq!(_20, cast(20u32).unwrap());
188             assert_eq!(_20, cast(20u64).unwrap());
189             assert_eq!(_20, cast(20i).unwrap());
190             assert_eq!(_20, cast(20i8).unwrap());
191             assert_eq!(_20, cast(20i16).unwrap());
192             assert_eq!(_20, cast(20i32).unwrap());
193             assert_eq!(_20, cast(20i64).unwrap());
194             assert_eq!(_20, cast(20f32).unwrap());
195             assert_eq!(_20, cast(20f64).unwrap());
196         })
197     }
198
199     #[test] fn test_u8_cast()    { test_cast_20!(20u8)  }
200     #[test] fn test_u16_cast()   { test_cast_20!(20u16) }
201     #[test] fn test_u32_cast()   { test_cast_20!(20u32) }
202     #[test] fn test_u64_cast()   { test_cast_20!(20u64) }
203     #[test] fn test_uint_cast()  { test_cast_20!(20u)   }
204     #[test] fn test_i8_cast()    { test_cast_20!(20i8)  }
205     #[test] fn test_i16_cast()   { test_cast_20!(20i16) }
206     #[test] fn test_i32_cast()   { test_cast_20!(20i32) }
207     #[test] fn test_i64_cast()   { test_cast_20!(20i64) }
208     #[test] fn test_int_cast()   { test_cast_20!(20i)   }
209     #[test] fn test_f32_cast()   { test_cast_20!(20f32) }
210     #[test] fn test_f64_cast()   { test_cast_20!(20f64) }
211
212     #[test]
213     fn test_cast_range_int_min() {
214         assert_eq!(int::MIN.to_int(),  Some(int::MIN as int));
215         assert_eq!(int::MIN.to_i8(),   None);
216         assert_eq!(int::MIN.to_i16(),  None);
217         // int::MIN.to_i32() is word-size specific
218         assert_eq!(int::MIN.to_i64(),  Some(int::MIN as i64));
219         assert_eq!(int::MIN.to_uint(), None);
220         assert_eq!(int::MIN.to_u8(),   None);
221         assert_eq!(int::MIN.to_u16(),  None);
222         assert_eq!(int::MIN.to_u32(),  None);
223         assert_eq!(int::MIN.to_u64(),  None);
224
225         #[cfg(target_word_size = "32")]
226         fn check_word_size() {
227             assert_eq!(int::MIN.to_i32(), Some(int::MIN as i32));
228         }
229
230         #[cfg(target_word_size = "64")]
231         fn check_word_size() {
232             assert_eq!(int::MIN.to_i32(), None);
233         }
234
235         check_word_size();
236     }
237
238     #[test]
239     fn test_cast_range_i8_min() {
240         assert_eq!(i8::MIN.to_int(),  Some(i8::MIN as int));
241         assert_eq!(i8::MIN.to_i8(),   Some(i8::MIN as i8));
242         assert_eq!(i8::MIN.to_i16(),  Some(i8::MIN as i16));
243         assert_eq!(i8::MIN.to_i32(),  Some(i8::MIN as i32));
244         assert_eq!(i8::MIN.to_i64(),  Some(i8::MIN as i64));
245         assert_eq!(i8::MIN.to_uint(), None);
246         assert_eq!(i8::MIN.to_u8(),   None);
247         assert_eq!(i8::MIN.to_u16(),  None);
248         assert_eq!(i8::MIN.to_u32(),  None);
249         assert_eq!(i8::MIN.to_u64(),  None);
250     }
251
252     #[test]
253     fn test_cast_range_i16_min() {
254         assert_eq!(i16::MIN.to_int(),  Some(i16::MIN as int));
255         assert_eq!(i16::MIN.to_i8(),   None);
256         assert_eq!(i16::MIN.to_i16(),  Some(i16::MIN as i16));
257         assert_eq!(i16::MIN.to_i32(),  Some(i16::MIN as i32));
258         assert_eq!(i16::MIN.to_i64(),  Some(i16::MIN as i64));
259         assert_eq!(i16::MIN.to_uint(), None);
260         assert_eq!(i16::MIN.to_u8(),   None);
261         assert_eq!(i16::MIN.to_u16(),  None);
262         assert_eq!(i16::MIN.to_u32(),  None);
263         assert_eq!(i16::MIN.to_u64(),  None);
264     }
265
266     #[test]
267     fn test_cast_range_i32_min() {
268         assert_eq!(i32::MIN.to_int(),  Some(i32::MIN as int));
269         assert_eq!(i32::MIN.to_i8(),   None);
270         assert_eq!(i32::MIN.to_i16(),  None);
271         assert_eq!(i32::MIN.to_i32(),  Some(i32::MIN as i32));
272         assert_eq!(i32::MIN.to_i64(),  Some(i32::MIN as i64));
273         assert_eq!(i32::MIN.to_uint(), None);
274         assert_eq!(i32::MIN.to_u8(),   None);
275         assert_eq!(i32::MIN.to_u16(),  None);
276         assert_eq!(i32::MIN.to_u32(),  None);
277         assert_eq!(i32::MIN.to_u64(),  None);
278     }
279
280     #[test]
281     fn test_cast_range_i64_min() {
282         // i64::MIN.to_int() is word-size specific
283         assert_eq!(i64::MIN.to_i8(),   None);
284         assert_eq!(i64::MIN.to_i16(),  None);
285         assert_eq!(i64::MIN.to_i32(),  None);
286         assert_eq!(i64::MIN.to_i64(),  Some(i64::MIN as i64));
287         assert_eq!(i64::MIN.to_uint(), None);
288         assert_eq!(i64::MIN.to_u8(),   None);
289         assert_eq!(i64::MIN.to_u16(),  None);
290         assert_eq!(i64::MIN.to_u32(),  None);
291         assert_eq!(i64::MIN.to_u64(),  None);
292
293         #[cfg(target_word_size = "32")]
294         fn check_word_size() {
295             assert_eq!(i64::MIN.to_int(), None);
296         }
297
298         #[cfg(target_word_size = "64")]
299         fn check_word_size() {
300             assert_eq!(i64::MIN.to_int(), Some(i64::MIN as int));
301         }
302
303         check_word_size();
304     }
305
306     #[test]
307     fn test_cast_range_int_max() {
308         assert_eq!(int::MAX.to_int(),  Some(int::MAX as int));
309         assert_eq!(int::MAX.to_i8(),   None);
310         assert_eq!(int::MAX.to_i16(),  None);
311         // int::MAX.to_i32() is word-size specific
312         assert_eq!(int::MAX.to_i64(),  Some(int::MAX as i64));
313         assert_eq!(int::MAX.to_u8(),   None);
314         assert_eq!(int::MAX.to_u16(),  None);
315         // int::MAX.to_u32() is word-size specific
316         assert_eq!(int::MAX.to_u64(),  Some(int::MAX as u64));
317
318         #[cfg(target_word_size = "32")]
319         fn check_word_size() {
320             assert_eq!(int::MAX.to_i32(), Some(int::MAX as i32));
321             assert_eq!(int::MAX.to_u32(), Some(int::MAX as u32));
322         }
323
324         #[cfg(target_word_size = "64")]
325         fn check_word_size() {
326             assert_eq!(int::MAX.to_i32(), None);
327             assert_eq!(int::MAX.to_u32(), None);
328         }
329
330         check_word_size();
331     }
332
333     #[test]
334     fn test_cast_range_i8_max() {
335         assert_eq!(i8::MAX.to_int(),  Some(i8::MAX as int));
336         assert_eq!(i8::MAX.to_i8(),   Some(i8::MAX as i8));
337         assert_eq!(i8::MAX.to_i16(),  Some(i8::MAX as i16));
338         assert_eq!(i8::MAX.to_i32(),  Some(i8::MAX as i32));
339         assert_eq!(i8::MAX.to_i64(),  Some(i8::MAX as i64));
340         assert_eq!(i8::MAX.to_uint(), Some(i8::MAX as uint));
341         assert_eq!(i8::MAX.to_u8(),   Some(i8::MAX as u8));
342         assert_eq!(i8::MAX.to_u16(),  Some(i8::MAX as u16));
343         assert_eq!(i8::MAX.to_u32(),  Some(i8::MAX as u32));
344         assert_eq!(i8::MAX.to_u64(),  Some(i8::MAX as u64));
345     }
346
347     #[test]
348     fn test_cast_range_i16_max() {
349         assert_eq!(i16::MAX.to_int(),  Some(i16::MAX as int));
350         assert_eq!(i16::MAX.to_i8(),   None);
351         assert_eq!(i16::MAX.to_i16(),  Some(i16::MAX as i16));
352         assert_eq!(i16::MAX.to_i32(),  Some(i16::MAX as i32));
353         assert_eq!(i16::MAX.to_i64(),  Some(i16::MAX as i64));
354         assert_eq!(i16::MAX.to_uint(), Some(i16::MAX as uint));
355         assert_eq!(i16::MAX.to_u8(),   None);
356         assert_eq!(i16::MAX.to_u16(),  Some(i16::MAX as u16));
357         assert_eq!(i16::MAX.to_u32(),  Some(i16::MAX as u32));
358         assert_eq!(i16::MAX.to_u64(),  Some(i16::MAX as u64));
359     }
360
361     #[test]
362     fn test_cast_range_i32_max() {
363         assert_eq!(i32::MAX.to_int(),  Some(i32::MAX as int));
364         assert_eq!(i32::MAX.to_i8(),   None);
365         assert_eq!(i32::MAX.to_i16(),  None);
366         assert_eq!(i32::MAX.to_i32(),  Some(i32::MAX as i32));
367         assert_eq!(i32::MAX.to_i64(),  Some(i32::MAX as i64));
368         assert_eq!(i32::MAX.to_uint(), Some(i32::MAX as uint));
369         assert_eq!(i32::MAX.to_u8(),   None);
370         assert_eq!(i32::MAX.to_u16(),  None);
371         assert_eq!(i32::MAX.to_u32(),  Some(i32::MAX as u32));
372         assert_eq!(i32::MAX.to_u64(),  Some(i32::MAX as u64));
373     }
374
375     #[test]
376     fn test_cast_range_i64_max() {
377         // i64::MAX.to_int() is word-size specific
378         assert_eq!(i64::MAX.to_i8(),   None);
379         assert_eq!(i64::MAX.to_i16(),  None);
380         assert_eq!(i64::MAX.to_i32(),  None);
381         assert_eq!(i64::MAX.to_i64(),  Some(i64::MAX as i64));
382         // i64::MAX.to_uint() is word-size specific
383         assert_eq!(i64::MAX.to_u8(),   None);
384         assert_eq!(i64::MAX.to_u16(),  None);
385         assert_eq!(i64::MAX.to_u32(),  None);
386         assert_eq!(i64::MAX.to_u64(),  Some(i64::MAX as u64));
387
388         #[cfg(target_word_size = "32")]
389         fn check_word_size() {
390             assert_eq!(i64::MAX.to_int(),  None);
391             assert_eq!(i64::MAX.to_uint(), None);
392         }
393
394         #[cfg(target_word_size = "64")]
395         fn check_word_size() {
396             assert_eq!(i64::MAX.to_int(),  Some(i64::MAX as int));
397             assert_eq!(i64::MAX.to_uint(), Some(i64::MAX as uint));
398         }
399
400         check_word_size();
401     }
402
403     #[test]
404     fn test_cast_range_uint_min() {
405         assert_eq!(uint::MIN.to_int(),  Some(uint::MIN as int));
406         assert_eq!(uint::MIN.to_i8(),   Some(uint::MIN as i8));
407         assert_eq!(uint::MIN.to_i16(),  Some(uint::MIN as i16));
408         assert_eq!(uint::MIN.to_i32(),  Some(uint::MIN as i32));
409         assert_eq!(uint::MIN.to_i64(),  Some(uint::MIN as i64));
410         assert_eq!(uint::MIN.to_uint(), Some(uint::MIN as uint));
411         assert_eq!(uint::MIN.to_u8(),   Some(uint::MIN as u8));
412         assert_eq!(uint::MIN.to_u16(),  Some(uint::MIN as u16));
413         assert_eq!(uint::MIN.to_u32(),  Some(uint::MIN as u32));
414         assert_eq!(uint::MIN.to_u64(),  Some(uint::MIN as u64));
415     }
416
417     #[test]
418     fn test_cast_range_u8_min() {
419         assert_eq!(u8::MIN.to_int(),  Some(u8::MIN as int));
420         assert_eq!(u8::MIN.to_i8(),   Some(u8::MIN as i8));
421         assert_eq!(u8::MIN.to_i16(),  Some(u8::MIN as i16));
422         assert_eq!(u8::MIN.to_i32(),  Some(u8::MIN as i32));
423         assert_eq!(u8::MIN.to_i64(),  Some(u8::MIN as i64));
424         assert_eq!(u8::MIN.to_uint(), Some(u8::MIN as uint));
425         assert_eq!(u8::MIN.to_u8(),   Some(u8::MIN as u8));
426         assert_eq!(u8::MIN.to_u16(),  Some(u8::MIN as u16));
427         assert_eq!(u8::MIN.to_u32(),  Some(u8::MIN as u32));
428         assert_eq!(u8::MIN.to_u64(),  Some(u8::MIN as u64));
429     }
430
431     #[test]
432     fn test_cast_range_u16_min() {
433         assert_eq!(u16::MIN.to_int(),  Some(u16::MIN as int));
434         assert_eq!(u16::MIN.to_i8(),   Some(u16::MIN as i8));
435         assert_eq!(u16::MIN.to_i16(),  Some(u16::MIN as i16));
436         assert_eq!(u16::MIN.to_i32(),  Some(u16::MIN as i32));
437         assert_eq!(u16::MIN.to_i64(),  Some(u16::MIN as i64));
438         assert_eq!(u16::MIN.to_uint(), Some(u16::MIN as uint));
439         assert_eq!(u16::MIN.to_u8(),   Some(u16::MIN as u8));
440         assert_eq!(u16::MIN.to_u16(),  Some(u16::MIN as u16));
441         assert_eq!(u16::MIN.to_u32(),  Some(u16::MIN as u32));
442         assert_eq!(u16::MIN.to_u64(),  Some(u16::MIN as u64));
443     }
444
445     #[test]
446     fn test_cast_range_u32_min() {
447         assert_eq!(u32::MIN.to_int(),  Some(u32::MIN as int));
448         assert_eq!(u32::MIN.to_i8(),   Some(u32::MIN as i8));
449         assert_eq!(u32::MIN.to_i16(),  Some(u32::MIN as i16));
450         assert_eq!(u32::MIN.to_i32(),  Some(u32::MIN as i32));
451         assert_eq!(u32::MIN.to_i64(),  Some(u32::MIN as i64));
452         assert_eq!(u32::MIN.to_uint(), Some(u32::MIN as uint));
453         assert_eq!(u32::MIN.to_u8(),   Some(u32::MIN as u8));
454         assert_eq!(u32::MIN.to_u16(),  Some(u32::MIN as u16));
455         assert_eq!(u32::MIN.to_u32(),  Some(u32::MIN as u32));
456         assert_eq!(u32::MIN.to_u64(),  Some(u32::MIN as u64));
457     }
458
459     #[test]
460     fn test_cast_range_u64_min() {
461         assert_eq!(u64::MIN.to_int(),  Some(u64::MIN as int));
462         assert_eq!(u64::MIN.to_i8(),   Some(u64::MIN as i8));
463         assert_eq!(u64::MIN.to_i16(),  Some(u64::MIN as i16));
464         assert_eq!(u64::MIN.to_i32(),  Some(u64::MIN as i32));
465         assert_eq!(u64::MIN.to_i64(),  Some(u64::MIN as i64));
466         assert_eq!(u64::MIN.to_uint(), Some(u64::MIN as uint));
467         assert_eq!(u64::MIN.to_u8(),   Some(u64::MIN as u8));
468         assert_eq!(u64::MIN.to_u16(),  Some(u64::MIN as u16));
469         assert_eq!(u64::MIN.to_u32(),  Some(u64::MIN as u32));
470         assert_eq!(u64::MIN.to_u64(),  Some(u64::MIN as u64));
471     }
472
473     #[test]
474     fn test_cast_range_uint_max() {
475         assert_eq!(uint::MAX.to_int(),  None);
476         assert_eq!(uint::MAX.to_i8(),   None);
477         assert_eq!(uint::MAX.to_i16(),  None);
478         assert_eq!(uint::MAX.to_i32(),  None);
479         // uint::MAX.to_i64() is word-size specific
480         assert_eq!(uint::MAX.to_u8(),   None);
481         assert_eq!(uint::MAX.to_u16(),  None);
482         // uint::MAX.to_u32() is word-size specific
483         assert_eq!(uint::MAX.to_u64(),  Some(uint::MAX as u64));
484
485         #[cfg(target_word_size = "32")]
486         fn check_word_size() {
487             assert_eq!(uint::MAX.to_u32(), Some(uint::MAX as u32));
488             assert_eq!(uint::MAX.to_i64(), Some(uint::MAX as i64));
489         }
490
491         #[cfg(target_word_size = "64")]
492         fn check_word_size() {
493             assert_eq!(uint::MAX.to_u32(), None);
494             assert_eq!(uint::MAX.to_i64(), None);
495         }
496
497         check_word_size();
498     }
499
500     #[test]
501     fn test_cast_range_u8_max() {
502         assert_eq!(u8::MAX.to_int(),  Some(u8::MAX as int));
503         assert_eq!(u8::MAX.to_i8(),   None);
504         assert_eq!(u8::MAX.to_i16(),  Some(u8::MAX as i16));
505         assert_eq!(u8::MAX.to_i32(),  Some(u8::MAX as i32));
506         assert_eq!(u8::MAX.to_i64(),  Some(u8::MAX as i64));
507         assert_eq!(u8::MAX.to_uint(), Some(u8::MAX as uint));
508         assert_eq!(u8::MAX.to_u8(),   Some(u8::MAX as u8));
509         assert_eq!(u8::MAX.to_u16(),  Some(u8::MAX as u16));
510         assert_eq!(u8::MAX.to_u32(),  Some(u8::MAX as u32));
511         assert_eq!(u8::MAX.to_u64(),  Some(u8::MAX as u64));
512     }
513
514     #[test]
515     fn test_cast_range_u16_max() {
516         assert_eq!(u16::MAX.to_int(),  Some(u16::MAX as int));
517         assert_eq!(u16::MAX.to_i8(),   None);
518         assert_eq!(u16::MAX.to_i16(),  None);
519         assert_eq!(u16::MAX.to_i32(),  Some(u16::MAX as i32));
520         assert_eq!(u16::MAX.to_i64(),  Some(u16::MAX as i64));
521         assert_eq!(u16::MAX.to_uint(), Some(u16::MAX as uint));
522         assert_eq!(u16::MAX.to_u8(),   None);
523         assert_eq!(u16::MAX.to_u16(),  Some(u16::MAX as u16));
524         assert_eq!(u16::MAX.to_u32(),  Some(u16::MAX as u32));
525         assert_eq!(u16::MAX.to_u64(),  Some(u16::MAX as u64));
526     }
527
528     #[test]
529     fn test_cast_range_u32_max() {
530         // u32::MAX.to_int() is word-size specific
531         assert_eq!(u32::MAX.to_i8(),   None);
532         assert_eq!(u32::MAX.to_i16(),  None);
533         assert_eq!(u32::MAX.to_i32(),  None);
534         assert_eq!(u32::MAX.to_i64(),  Some(u32::MAX as i64));
535         assert_eq!(u32::MAX.to_uint(), Some(u32::MAX as uint));
536         assert_eq!(u32::MAX.to_u8(),   None);
537         assert_eq!(u32::MAX.to_u16(),  None);
538         assert_eq!(u32::MAX.to_u32(),  Some(u32::MAX as u32));
539         assert_eq!(u32::MAX.to_u64(),  Some(u32::MAX as u64));
540
541         #[cfg(target_word_size = "32")]
542         fn check_word_size() {
543             assert_eq!(u32::MAX.to_int(),  None);
544         }
545
546         #[cfg(target_word_size = "64")]
547         fn check_word_size() {
548             assert_eq!(u32::MAX.to_int(),  Some(u32::MAX as int));
549         }
550
551         check_word_size();
552     }
553
554     #[test]
555     fn test_cast_range_u64_max() {
556         assert_eq!(u64::MAX.to_int(),  None);
557         assert_eq!(u64::MAX.to_i8(),   None);
558         assert_eq!(u64::MAX.to_i16(),  None);
559         assert_eq!(u64::MAX.to_i32(),  None);
560         assert_eq!(u64::MAX.to_i64(),  None);
561         // u64::MAX.to_uint() is word-size specific
562         assert_eq!(u64::MAX.to_u8(),   None);
563         assert_eq!(u64::MAX.to_u16(),  None);
564         assert_eq!(u64::MAX.to_u32(),  None);
565         assert_eq!(u64::MAX.to_u64(),  Some(u64::MAX as u64));
566
567         #[cfg(target_word_size = "32")]
568         fn check_word_size() {
569             assert_eq!(u64::MAX.to_uint(), None);
570         }
571
572         #[cfg(target_word_size = "64")]
573         fn check_word_size() {
574             assert_eq!(u64::MAX.to_uint(), Some(u64::MAX as uint));
575         }
576
577         check_word_size();
578     }
579
580     #[test]
581     fn test_saturating_add_uint() {
582         use uint::MAX;
583         assert_eq!(3u.saturating_add(5u), 8u);
584         assert_eq!(3u.saturating_add(MAX-1), MAX);
585         assert_eq!(MAX.saturating_add(MAX), MAX);
586         assert_eq!((MAX-2).saturating_add(1), MAX-1);
587     }
588
589     #[test]
590     fn test_saturating_sub_uint() {
591         use uint::MAX;
592         assert_eq!(5u.saturating_sub(3u), 2u);
593         assert_eq!(3u.saturating_sub(5u), 0u);
594         assert_eq!(0u.saturating_sub(1u), 0u);
595         assert_eq!((MAX-1).saturating_sub(MAX), 0);
596     }
597
598     #[test]
599     fn test_saturating_add_int() {
600         use int::{MIN,MAX};
601         assert_eq!(3i.saturating_add(5i), 8i);
602         assert_eq!(3i.saturating_add(MAX-1), MAX);
603         assert_eq!(MAX.saturating_add(MAX), MAX);
604         assert_eq!((MAX-2).saturating_add(1), MAX-1);
605         assert_eq!(3i.saturating_add(-5i), -2i);
606         assert_eq!(MIN.saturating_add(-1i), MIN);
607         assert_eq!((-2i).saturating_add(-MAX), MIN);
608     }
609
610     #[test]
611     fn test_saturating_sub_int() {
612         use int::{MIN,MAX};
613         assert_eq!(3i.saturating_sub(5i), -2i);
614         assert_eq!(MIN.saturating_sub(1i), MIN);
615         assert_eq!((-2i).saturating_sub(MAX), MIN);
616         assert_eq!(3i.saturating_sub(-5i), 8i);
617         assert_eq!(3i.saturating_sub(-(MAX-1)), MAX);
618         assert_eq!(MAX.saturating_sub(-MAX), MAX);
619         assert_eq!((MAX-2).saturating_sub(-1), MAX-1);
620     }
621
622     #[test]
623     fn test_checked_add() {
624         let five_less = uint::MAX - 5;
625         assert_eq!(five_less.checked_add(0), Some(uint::MAX - 5));
626         assert_eq!(five_less.checked_add(1), Some(uint::MAX - 4));
627         assert_eq!(five_less.checked_add(2), Some(uint::MAX - 3));
628         assert_eq!(five_less.checked_add(3), Some(uint::MAX - 2));
629         assert_eq!(five_less.checked_add(4), Some(uint::MAX - 1));
630         assert_eq!(five_less.checked_add(5), Some(uint::MAX));
631         assert_eq!(five_less.checked_add(6), None);
632         assert_eq!(five_less.checked_add(7), None);
633     }
634
635     #[test]
636     fn test_checked_sub() {
637         assert_eq!(5u.checked_sub(0), Some(5));
638         assert_eq!(5u.checked_sub(1), Some(4));
639         assert_eq!(5u.checked_sub(2), Some(3));
640         assert_eq!(5u.checked_sub(3), Some(2));
641         assert_eq!(5u.checked_sub(4), Some(1));
642         assert_eq!(5u.checked_sub(5), Some(0));
643         assert_eq!(5u.checked_sub(6), None);
644         assert_eq!(5u.checked_sub(7), None);
645     }
646
647     #[test]
648     fn test_checked_mul() {
649         let third = uint::MAX / 3;
650         assert_eq!(third.checked_mul(0), Some(0));
651         assert_eq!(third.checked_mul(1), Some(third));
652         assert_eq!(third.checked_mul(2), Some(third * 2));
653         assert_eq!(third.checked_mul(3), Some(third * 3));
654         assert_eq!(third.checked_mul(4), None);
655     }
656
657     macro_rules! test_is_power_of_two {
658         ($test_name:ident, $T:ident) => (
659             fn $test_name() {
660                 #![test]
661                 assert_eq!((0 as $T).is_power_of_two(), false);
662                 assert_eq!((1 as $T).is_power_of_two(), true);
663                 assert_eq!((2 as $T).is_power_of_two(), true);
664                 assert_eq!((3 as $T).is_power_of_two(), false);
665                 assert_eq!((4 as $T).is_power_of_two(), true);
666                 assert_eq!((5 as $T).is_power_of_two(), false);
667                 assert!(($T::MAX / 2 + 1).is_power_of_two(), true);
668             }
669         )
670     }
671
672     test_is_power_of_two!{ test_is_power_of_two_u8, u8 }
673     test_is_power_of_two!{ test_is_power_of_two_u16, u16 }
674     test_is_power_of_two!{ test_is_power_of_two_u32, u32 }
675     test_is_power_of_two!{ test_is_power_of_two_u64, u64 }
676     test_is_power_of_two!{ test_is_power_of_two_uint, uint }
677
678     macro_rules! test_next_power_of_two {
679         ($test_name:ident, $T:ident) => (
680             fn $test_name() {
681                 #![test]
682                 assert_eq!((0 as $T).next_power_of_two(), 1);
683                 let mut next_power = 1;
684                 for i in range::<$T>(1, 40) {
685                      assert_eq!(i.next_power_of_two(), next_power);
686                      if i == next_power { next_power *= 2 }
687                 }
688             }
689         )
690     }
691
692     test_next_power_of_two! { test_next_power_of_two_u8, u8 }
693     test_next_power_of_two! { test_next_power_of_two_u16, u16 }
694     test_next_power_of_two! { test_next_power_of_two_u32, u32 }
695     test_next_power_of_two! { test_next_power_of_two_u64, u64 }
696     test_next_power_of_two! { test_next_power_of_two_uint, uint }
697
698     macro_rules! test_checked_next_power_of_two {
699         ($test_name:ident, $T:ident) => (
700             fn $test_name() {
701                 #![test]
702                 assert_eq!((0 as $T).checked_next_power_of_two(), Some(1));
703                 assert!(($T::MAX / 2).checked_next_power_of_two().is_some());
704                 assert_eq!(($T::MAX - 1).checked_next_power_of_two(), None);
705                 assert_eq!($T::MAX.checked_next_power_of_two(), None);
706                 let mut next_power = 1;
707                 for i in range::<$T>(1, 40) {
708                      assert_eq!(i.checked_next_power_of_two(), Some(next_power));
709                      if i == next_power { next_power *= 2 }
710                 }
711             }
712         )
713     }
714
715     test_checked_next_power_of_two! { test_checked_next_power_of_two_u8, u8 }
716     test_checked_next_power_of_two! { test_checked_next_power_of_two_u16, u16 }
717     test_checked_next_power_of_two! { test_checked_next_power_of_two_u32, u32 }
718     test_checked_next_power_of_two! { test_checked_next_power_of_two_u64, u64 }
719     test_checked_next_power_of_two! { test_checked_next_power_of_two_uint, uint }
720
721     #[derive(PartialEq, Show)]
722     struct Value { x: int }
723
724     impl ToPrimitive for Value {
725         fn to_i64(&self) -> Option<i64> { self.x.to_i64() }
726         fn to_u64(&self) -> Option<u64> { self.x.to_u64() }
727     }
728
729     impl FromPrimitive for Value {
730         fn from_i64(n: i64) -> Option<Value> { Some(Value { x: n as int }) }
731         fn from_u64(n: u64) -> Option<Value> { Some(Value { x: n as int }) }
732     }
733
734     #[test]
735     fn test_to_primitive() {
736         let value = Value { x: 5 };
737         assert_eq!(value.to_int(),  Some(5));
738         assert_eq!(value.to_i8(),   Some(5));
739         assert_eq!(value.to_i16(),  Some(5));
740         assert_eq!(value.to_i32(),  Some(5));
741         assert_eq!(value.to_i64(),  Some(5));
742         assert_eq!(value.to_uint(), Some(5));
743         assert_eq!(value.to_u8(),   Some(5));
744         assert_eq!(value.to_u16(),  Some(5));
745         assert_eq!(value.to_u32(),  Some(5));
746         assert_eq!(value.to_u64(),  Some(5));
747         assert_eq!(value.to_f32(),  Some(5f32));
748         assert_eq!(value.to_f64(),  Some(5f64));
749     }
750
751     #[test]
752     fn test_from_primitive() {
753         assert_eq!(from_int(5),    Some(Value { x: 5 }));
754         assert_eq!(from_i8(5),     Some(Value { x: 5 }));
755         assert_eq!(from_i16(5),    Some(Value { x: 5 }));
756         assert_eq!(from_i32(5),    Some(Value { x: 5 }));
757         assert_eq!(from_i64(5),    Some(Value { x: 5 }));
758         assert_eq!(from_uint(5),   Some(Value { x: 5 }));
759         assert_eq!(from_u8(5),     Some(Value { x: 5 }));
760         assert_eq!(from_u16(5),    Some(Value { x: 5 }));
761         assert_eq!(from_u32(5),    Some(Value { x: 5 }));
762         assert_eq!(from_u64(5),    Some(Value { x: 5 }));
763         assert_eq!(from_f32(5f32), Some(Value { x: 5 }));
764         assert_eq!(from_f64(5f64), Some(Value { x: 5 }));
765     }
766
767     #[test]
768     fn test_pow() {
769         fn naive_pow<T: Int>(base: T, exp: uint) -> T {
770             let one: T = Int::one();
771             range(0, exp).fold(one, |acc, _| acc * base)
772         }
773         macro_rules! assert_pow {
774             (($num:expr, $exp:expr) => $expected:expr) => {{
775                 let result = $num.pow($exp);
776                 assert_eq!(result, $expected);
777                 assert_eq!(result, naive_pow($num, $exp));
778             }}
779         }
780         assert_pow!((3i,     0 ) => 1);
781         assert_pow!((5i,     1 ) => 5);
782         assert_pow!((-4i,    2 ) => 16);
783         assert_pow!((8i,     3 ) => 512);
784         assert_pow!((2u64,   50) => 1125899906842624);
785     }
786 }
787
788
789 #[cfg(test)]
790 mod bench {
791     extern crate test;
792     use self::test::Bencher;
793     use num::Int;
794     use prelude::v1::*;
795
796     #[bench]
797     fn bench_pow_function(b: &mut Bencher) {
798         let v = range(0, 1024u).collect::<Vec<_>>();
799         b.iter(|| {v.iter().fold(0u, |old, new| old.pow(*new));});
800     }
801 }