]> git.proxmox.com Git - rustc.git/blob - src/libstd/num/mod.rs
Imported Upstream version 1.9.0+dfsg1
[rustc.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 //! Additional functionality for numerics.
12 //!
13 //! This module provides some extra types that are useful when doing numerical
14 //! work. See the individual documentation for each piece for more information.
15
16 #![stable(feature = "rust1", since = "1.0.0")]
17 #![allow(missing_docs)]
18
19 #[stable(feature = "rust1", since = "1.0.0")]
20 pub use core::num::{Zero, One};
21 #[stable(feature = "rust1", since = "1.0.0")]
22 pub use core::num::{FpCategory, ParseIntError, ParseFloatError};
23 #[stable(feature = "rust1", since = "1.0.0")]
24 pub use core::num::Wrapping;
25
26 #[cfg(test)] use cmp::PartialEq;
27 #[cfg(test)] use fmt;
28 #[cfg(test)] use marker::Copy;
29 #[cfg(test)] use ops::{Add, Sub, Mul, Div, Rem};
30
31 /// Helper function for testing numeric operations
32 #[cfg(test)]
33 pub fn test_num<T>(ten: T, two: T) where
34 T: PartialEq
35 + Add<Output=T> + Sub<Output=T>
36 + Mul<Output=T> + Div<Output=T>
37 + Rem<Output=T> + fmt::Debug
38 + Copy
39 {
40 assert_eq!(ten.add(two), ten + two);
41 assert_eq!(ten.sub(two), ten - two);
42 assert_eq!(ten.mul(two), ten * two);
43 assert_eq!(ten.div(two), ten / two);
44 assert_eq!(ten.rem(two), ten % two);
45 }
46
47 #[cfg(test)]
48 mod tests {
49 use super::*;
50 use u8;
51 use u16;
52 use u32;
53 use u64;
54 use usize;
55 use string::ToString;
56 use ops::Mul;
57
58 #[test]
59 fn test_saturating_add_uint() {
60 use usize::MAX;
61 assert_eq!(3_usize.saturating_add(5_usize), 8_usize);
62 assert_eq!(3_usize.saturating_add(MAX-1), MAX);
63 assert_eq!(MAX.saturating_add(MAX), MAX);
64 assert_eq!((MAX-2).saturating_add(1), MAX-1);
65 }
66
67 #[test]
68 fn test_saturating_sub_uint() {
69 use usize::MAX;
70 assert_eq!(5_usize.saturating_sub(3_usize), 2_usize);
71 assert_eq!(3_usize.saturating_sub(5_usize), 0_usize);
72 assert_eq!(0_usize.saturating_sub(1_usize), 0_usize);
73 assert_eq!((MAX-1).saturating_sub(MAX), 0);
74 }
75
76 #[test]
77 fn test_saturating_add_int() {
78 use isize::{MIN,MAX};
79 assert_eq!(3i32.saturating_add(5), 8);
80 assert_eq!(3isize.saturating_add(MAX-1), MAX);
81 assert_eq!(MAX.saturating_add(MAX), MAX);
82 assert_eq!((MAX-2).saturating_add(1), MAX-1);
83 assert_eq!(3i32.saturating_add(-5), -2);
84 assert_eq!(MIN.saturating_add(-1), MIN);
85 assert_eq!((-2isize).saturating_add(-MAX), MIN);
86 }
87
88 #[test]
89 fn test_saturating_sub_int() {
90 use isize::{MIN,MAX};
91 assert_eq!(3i32.saturating_sub(5), -2);
92 assert_eq!(MIN.saturating_sub(1), MIN);
93 assert_eq!((-2isize).saturating_sub(MAX), MIN);
94 assert_eq!(3i32.saturating_sub(-5), 8);
95 assert_eq!(3isize.saturating_sub(-(MAX-1)), MAX);
96 assert_eq!(MAX.saturating_sub(-MAX), MAX);
97 assert_eq!((MAX-2).saturating_sub(-1), MAX-1);
98 }
99
100 #[test]
101 fn test_checked_add() {
102 let five_less = usize::MAX - 5;
103 assert_eq!(five_less.checked_add(0), Some(usize::MAX - 5));
104 assert_eq!(five_less.checked_add(1), Some(usize::MAX - 4));
105 assert_eq!(five_less.checked_add(2), Some(usize::MAX - 3));
106 assert_eq!(five_less.checked_add(3), Some(usize::MAX - 2));
107 assert_eq!(five_less.checked_add(4), Some(usize::MAX - 1));
108 assert_eq!(five_less.checked_add(5), Some(usize::MAX));
109 assert_eq!(five_less.checked_add(6), None);
110 assert_eq!(five_less.checked_add(7), None);
111 }
112
113 #[test]
114 fn test_checked_sub() {
115 assert_eq!(5_usize.checked_sub(0), Some(5));
116 assert_eq!(5_usize.checked_sub(1), Some(4));
117 assert_eq!(5_usize.checked_sub(2), Some(3));
118 assert_eq!(5_usize.checked_sub(3), Some(2));
119 assert_eq!(5_usize.checked_sub(4), Some(1));
120 assert_eq!(5_usize.checked_sub(5), Some(0));
121 assert_eq!(5_usize.checked_sub(6), None);
122 assert_eq!(5_usize.checked_sub(7), None);
123 }
124
125 #[test]
126 fn test_checked_mul() {
127 let third = usize::MAX / 3;
128 assert_eq!(third.checked_mul(0), Some(0));
129 assert_eq!(third.checked_mul(1), Some(third));
130 assert_eq!(third.checked_mul(2), Some(third * 2));
131 assert_eq!(third.checked_mul(3), Some(third * 3));
132 assert_eq!(third.checked_mul(4), None);
133 }
134
135 macro_rules! test_is_power_of_two {
136 ($test_name:ident, $T:ident) => (
137 fn $test_name() {
138 #![test]
139 assert_eq!((0 as $T).is_power_of_two(), false);
140 assert_eq!((1 as $T).is_power_of_two(), true);
141 assert_eq!((2 as $T).is_power_of_two(), true);
142 assert_eq!((3 as $T).is_power_of_two(), false);
143 assert_eq!((4 as $T).is_power_of_two(), true);
144 assert_eq!((5 as $T).is_power_of_two(), false);
145 assert_eq!(($T::MAX / 2 + 1).is_power_of_two(), true);
146 }
147 )
148 }
149
150 test_is_power_of_two!{ test_is_power_of_two_u8, u8 }
151 test_is_power_of_two!{ test_is_power_of_two_u16, u16 }
152 test_is_power_of_two!{ test_is_power_of_two_u32, u32 }
153 test_is_power_of_two!{ test_is_power_of_two_u64, u64 }
154 test_is_power_of_two!{ test_is_power_of_two_uint, usize }
155
156 macro_rules! test_next_power_of_two {
157 ($test_name:ident, $T:ident) => (
158 fn $test_name() {
159 #![test]
160 assert_eq!((0 as $T).next_power_of_two(), 1);
161 let mut next_power = 1;
162 for i in 1 as $T..40 {
163 assert_eq!(i.next_power_of_two(), next_power);
164 if i == next_power { next_power *= 2 }
165 }
166 }
167 )
168 }
169
170 test_next_power_of_two! { test_next_power_of_two_u8, u8 }
171 test_next_power_of_two! { test_next_power_of_two_u16, u16 }
172 test_next_power_of_two! { test_next_power_of_two_u32, u32 }
173 test_next_power_of_two! { test_next_power_of_two_u64, u64 }
174 test_next_power_of_two! { test_next_power_of_two_uint, usize }
175
176 macro_rules! test_checked_next_power_of_two {
177 ($test_name:ident, $T:ident) => (
178 fn $test_name() {
179 #![test]
180 assert_eq!((0 as $T).checked_next_power_of_two(), Some(1));
181 assert!(($T::MAX / 2).checked_next_power_of_two().is_some());
182 assert_eq!(($T::MAX - 1).checked_next_power_of_two(), None);
183 assert_eq!($T::MAX.checked_next_power_of_two(), None);
184 let mut next_power = 1;
185 for i in 1 as $T..40 {
186 assert_eq!(i.checked_next_power_of_two(), Some(next_power));
187 if i == next_power { next_power *= 2 }
188 }
189 }
190 )
191 }
192
193 test_checked_next_power_of_two! { test_checked_next_power_of_two_u8, u8 }
194 test_checked_next_power_of_two! { test_checked_next_power_of_two_u16, u16 }
195 test_checked_next_power_of_two! { test_checked_next_power_of_two_u32, u32 }
196 test_checked_next_power_of_two! { test_checked_next_power_of_two_u64, u64 }
197 test_checked_next_power_of_two! { test_checked_next_power_of_two_uint, usize }
198
199 #[test]
200 fn test_pow() {
201 fn naive_pow<T: Mul<Output=T> + One + Copy>(base: T, exp: usize) -> T {
202 let one: T = T::one();
203 (0..exp).fold(one, |acc, _| acc * base)
204 }
205 macro_rules! assert_pow {
206 (($num:expr, $exp:expr) => $expected:expr) => {{
207 let result = $num.pow($exp);
208 assert_eq!(result, $expected);
209 assert_eq!(result, naive_pow($num, $exp));
210 }}
211 }
212 assert_pow!((3u32, 0 ) => 1);
213 assert_pow!((5u32, 1 ) => 5);
214 assert_pow!((-4i32, 2 ) => 16);
215 assert_pow!((8u32, 3 ) => 512);
216 assert_pow!((2u64, 50) => 1125899906842624);
217 }
218
219 #[test]
220 fn test_uint_to_str_overflow() {
221 let mut u8_val: u8 = 255;
222 assert_eq!(u8_val.to_string(), "255");
223
224 u8_val = u8_val.wrapping_add(1);
225 assert_eq!(u8_val.to_string(), "0");
226
227 let mut u16_val: u16 = 65_535;
228 assert_eq!(u16_val.to_string(), "65535");
229
230 u16_val = u16_val.wrapping_add(1);
231 assert_eq!(u16_val.to_string(), "0");
232
233 let mut u32_val: u32 = 4_294_967_295;
234 assert_eq!(u32_val.to_string(), "4294967295");
235
236 u32_val = u32_val.wrapping_add(1);
237 assert_eq!(u32_val.to_string(), "0");
238
239 let mut u64_val: u64 = 18_446_744_073_709_551_615;
240 assert_eq!(u64_val.to_string(), "18446744073709551615");
241
242 u64_val = u64_val.wrapping_add(1);
243 assert_eq!(u64_val.to_string(), "0");
244 }
245
246 fn from_str<T: ::str::FromStr>(t: &str) -> Option<T> {
247 ::str::FromStr::from_str(t).ok()
248 }
249
250 #[test]
251 fn test_uint_from_str_overflow() {
252 let mut u8_val: u8 = 255;
253 assert_eq!(from_str::<u8>("255"), Some(u8_val));
254 assert_eq!(from_str::<u8>("256"), None);
255
256 u8_val = u8_val.wrapping_add(1);
257 assert_eq!(from_str::<u8>("0"), Some(u8_val));
258 assert_eq!(from_str::<u8>("-1"), None);
259
260 let mut u16_val: u16 = 65_535;
261 assert_eq!(from_str::<u16>("65535"), Some(u16_val));
262 assert_eq!(from_str::<u16>("65536"), None);
263
264 u16_val = u16_val.wrapping_add(1);
265 assert_eq!(from_str::<u16>("0"), Some(u16_val));
266 assert_eq!(from_str::<u16>("-1"), None);
267
268 let mut u32_val: u32 = 4_294_967_295;
269 assert_eq!(from_str::<u32>("4294967295"), Some(u32_val));
270 assert_eq!(from_str::<u32>("4294967296"), None);
271
272 u32_val = u32_val.wrapping_add(1);
273 assert_eq!(from_str::<u32>("0"), Some(u32_val));
274 assert_eq!(from_str::<u32>("-1"), None);
275
276 let mut u64_val: u64 = 18_446_744_073_709_551_615;
277 assert_eq!(from_str::<u64>("18446744073709551615"), Some(u64_val));
278 assert_eq!(from_str::<u64>("18446744073709551616"), None);
279
280 u64_val = u64_val.wrapping_add(1);
281 assert_eq!(from_str::<u64>("0"), Some(u64_val));
282 assert_eq!(from_str::<u64>("-1"), None);
283 }
284 }
285
286
287 #[cfg(test)]
288 mod bench {
289 extern crate test;
290 use self::test::Bencher;
291 use prelude::v1::*;
292
293 #[bench]
294 fn bench_pow_function(b: &mut Bencher) {
295 let v = (0..1024).collect::<Vec<u32>>();
296 b.iter(|| {v.iter().fold(0u32, |old, new| old.pow(*new as u32));});
297 }
298 }