(index<- ) ./libstd/num/mod.rs
git branch: * master 5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
modified: Fri May 9 13:02:28 2014
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, float}`.
15
16 #![allow(missing_doc)]
17
18 use option::{Option};
19
20 #[cfg(test)] use fmt::Show;
21
22 pub use core::num::{Num, div_rem, Zero, zero, One, one};
23 pub use core::num::{Signed, abs, abs_sub, signum};
24 pub use core::num::{Unsigned, pow, Bounded, Bitwise};
25 pub use core::num::{Primitive, Int, Saturating};
26 pub use core::num::{CheckedAdd, CheckedSub, CheckedMul, CheckedDiv};
27 pub use core::num::{cast, FromPrimitive, NumCast, ToPrimitive};
28 pub use core::num::{next_power_of_two, is_power_of_two};
29 pub use core::num::{checked_next_power_of_two};
30 pub use core::num::{from_int, from_i8, from_i16, from_i32, from_i64};
31 pub use core::num::{from_uint, from_u8, from_u16, from_u32, from_u64};
32 pub use core::num::{from_f32, from_f64};
33
34 pub mod strconv;
35
36 /// Used for representing the classification of floating point numbers
37 #[deriving(Eq, Show)]
38 pub enum FPCategory {
39 /// "Not a Number", often obtained by dividing by zero
40 FPNaN,
41 /// Positive or negative infinity
42 FPInfinite ,
43 /// Positive or negative zero
44 FPZero,
45 /// De-normalized floating point representation (less precise than `FPNormal`)
46 FPSubnormal,
47 /// A regular floating point number
48 FPNormal,
49 }
50
51 /// Operations on primitive floating point numbers.
52 // FIXME(#5527): In a future version of Rust, many of these functions will
53 // become constants.
54 //
55 // FIXME(#8888): Several of these functions have a parameter named
56 // `unused_self`. Removing it requires #8888 to be fixed.
57 pub trait Float: Signed + Primitive {
58 /// Returns the NaN value.
59 fn nan() -> Self;
60 /// Returns the infinite value.
61 fn infinity() -> Self;
62 /// Returns the negative infinite value.
63 fn neg_infinity() -> Self;
64 /// Returns -0.0.
65 fn neg_zero() -> Self;
66
67 /// Returns true if this value is NaN and false otherwise.
68 fn is_nan(self) -> bool;
69 /// Returns true if this value is positive infinity or negative infinity and
70 /// false otherwise.
71 fn is_infinite(self) -> bool;
72 /// Returns true if this number is neither infinite nor NaN.
73 fn is_finite(self) -> bool;
74 /// Returns true if this number is neither zero, infinite, denormal, or NaN.
75 fn is_normal(self) -> bool;
76 /// Returns the category that this number falls into.
77 fn classify(self) -> FPCategory;
78
79 // FIXME (#5527): These should be associated constants
80
81 /// Returns the number of binary digits of mantissa that this type supports.
82 fn mantissa_digits(unused_self: Option<Self>) -> uint;
83 /// Returns the number of base-10 digits of precision that this type supports.
84 fn digits(unused_self: Option<Self>) -> uint;
85 /// Returns the difference between 1.0 and the smallest representable number larger than 1.0.
86 fn epsilon() -> Self;
87 /// Returns the minimum binary exponent that this type can represent.
88 fn min_exp(unused_self: Option<Self>) -> int;
89 /// Returns the maximum binary exponent that this type can represent.
90 fn max_exp(unused_self: Option<Self>) -> int;
91 /// Returns the minimum base-10 exponent that this type can represent.
92 fn min_10_exp(unused_self: Option<Self>) -> int;
93 /// Returns the maximum base-10 exponent that this type can represent.
94 fn max_10_exp(unused_self: Option<Self>) -> int;
95 /// Returns the smallest normalized positive number that this type can represent.
96 fn min_pos_value(unused_self: Option<Self>) -> Self;
97
98 /// Constructs a floating point number created by multiplying `x` by 2
99 /// raised to the power of `exp`.
100 fn ldexp(x: Self, exp: int) -> Self;
101 /// Breaks the number into a normalized fraction and a base-2 exponent,
102 /// satisfying:
103 ///
104 /// * `self = x * pow(2, exp)`
105 ///
106 /// * `0.5 <= abs(x) < 1.0`
107 fn frexp(self) -> (Self, int);
108 /// Returns the mantissa, exponent and sign as integers, respectively.
109 fn integer_decode(self) -> (u64, i16, i8);
110
111 /// Returns the next representable floating-point value in the direction of
112 /// `other`.
113 fn next_after(self, other: Self) -> Self;
114
115 /// Return the largest integer less than or equal to a number.
116 fn floor(self) -> Self;
117 /// Return the smallest integer greater than or equal to a number.
118 fn ceil(self) -> Self;
119 /// Return the nearest integer to a number. Round half-way cases away from
120 /// `0.0`.
121 fn round(self) -> Self;
122 /// Return the integer part of a number.
123 fn trunc(self) -> Self;
124 /// Return the fractional part of a number.
125 fn fract(self) -> Self;
126
127 /// Returns the maximum of the two numbers.
128 fn max(self, other: Self) -> Self;
129 /// Returns the minimum of the two numbers.
130 fn min(self, other: Self) -> Self;
131
132 /// Fused multiply-add. Computes `(self * a) + b` with only one rounding
133 /// error. This produces a more accurate result with better performance than
134 /// a separate multiplication operation followed by an add.
135 fn mul_add(self, a: Self, b: Self) -> Self;
136 /// Take the reciprocal (inverse) of a number, `1/x`.
137 fn recip(self) -> Self;
138
139 /// Raise a number to an integer power.
140 ///
141 /// Using this function is generally faster than using `powf`
142 fn powi(self, n: i32) -> Self;
143 /// Raise a number to a floating point power.
144 fn powf(self, n: Self) -> Self;
145
146 /// sqrt(2.0).
147 fn sqrt2() -> Self;
148 /// 1.0 / sqrt(2.0).
149 fn frac_1_sqrt2() -> Self;
150
151 /// Take the square root of a number.
152 fn sqrt(self) -> Self;
153 /// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
154 fn rsqrt(self) -> Self;
155 /// Take the cubic root of a number.
156 fn cbrt(self) -> Self;
157 /// Calculate the length of the hypotenuse of a right-angle triangle given
158 /// legs of length `x` and `y`.
159 fn hypot(self, other: Self) -> Self;
160
161 // FIXME (#5527): These should be associated constants
162
163 /// Archimedes' constant.
164 fn pi() -> Self;
165 /// 2.0 * pi.
166 fn two_pi() -> Self;
167 /// pi / 2.0.
168 fn frac_pi_2() -> Self;
169 /// pi / 3.0.
170 fn frac_pi_3() -> Self;
171 /// pi / 4.0.
172 fn frac_pi_4() -> Self;
173 /// pi / 6.0.
174 fn frac_pi_6() -> Self;
175 /// pi / 8.0.
176 fn frac_pi_8() -> Self;
177 /// 1.0 / pi.
178 fn frac_1_pi() -> Self;
179 /// 2.0 / pi.
180 fn frac_2_pi() -> Self;
181 /// 2.0 / sqrt(pi).
182 fn frac_2_sqrtpi() -> Self;
183
184 /// Computes the sine of a number (in radians).
185 fn sin(self) -> Self;
186 /// Computes the cosine of a number (in radians).
187 fn cos(self) -> Self;
188 /// Computes the tangent of a number (in radians).
189 fn tan(self) -> Self;
190
191 /// Computes the arcsine of a number. Return value is in radians in
192 /// the range [-pi/2, pi/2] or NaN if the number is outside the range
193 /// [-1, 1].
194 fn asin(self) -> Self;
195 /// Computes the arccosine of a number. Return value is in radians in
196 /// the range [0, pi] or NaN if the number is outside the range
197 /// [-1, 1].
198 fn acos(self) -> Self;
199 /// Computes the arctangent of a number. Return value is in radians in the
200 /// range [-pi/2, pi/2];
201 fn atan(self) -> Self;
202 /// Computes the four quadrant arctangent of a number, `y`, and another
203 /// number `x`. Return value is in radians in the range [-pi, pi].
204 fn atan2(self, other: Self) -> Self;
205 /// Simultaneously computes the sine and cosine of the number, `x`. Returns
206 /// `(sin(x), cos(x))`.
207 fn sin_cos(self) -> (Self, Self);
208
209 /// Euler's number.
210 fn e() -> Self;
211 /// log2(e).
212 fn log2_e() -> Self;
213 /// log10(e).
214 fn log10_e() -> Self;
215 /// ln(2.0).
216 fn ln_2() -> Self;
217 /// ln(10.0).
218 fn ln_10() -> Self;
219
220 /// Returns `e^(self)`, (the exponential function).
221 fn exp(self) -> Self;
222 /// Returns 2 raised to the power of the number, `2^(self)`.
223 fn exp2(self) -> Self;
224 /// Returns the exponential of the number, minus 1, in a way that is
225 /// accurate even if the number is close to zero.
226 fn exp_m1(self) -> Self;
227 /// Returns the natural logarithm of the number.
228 fn ln(self) -> Self;
229 /// Returns the logarithm of the number with respect to an arbitrary base.
230 fn log(self, base: Self) -> Self;
231 /// Returns the base 2 logarithm of the number.
232 fn log2(self) -> Self;
233 /// Returns the base 10 logarithm of the number.
234 fn log10(self) -> Self;
235 /// Returns the natural logarithm of the number plus 1 (`ln(1+n)`) more
236 /// accurately than if the operations were performed separately.
237 fn ln_1p(self) -> Self;
238
239 /// Hyperbolic sine function.
240 fn sinh(self) -> Self;
241 /// Hyperbolic cosine function.
242 fn cosh(self) -> Self;
243 /// Hyperbolic tangent function.
244 fn tanh(self) -> Self;
245 /// Inverse hyperbolic sine function.
246 fn asinh(self) -> Self;
247 /// Inverse hyperbolic cosine function.
248 fn acosh(self) -> Self;
249 /// Inverse hyperbolic tangent function.
250 fn atanh(self) -> Self;
251
252 /// Convert radians to degrees.
253 fn to_degrees(self) -> Self;
254 /// Convert degrees to radians.
255 fn to_radians(self) -> Self;
256 }
257
258 /// A generic trait for converting a value to a string with a radix (base)
259 pub trait ToStrRadix {
260 fn to_str_radix(&self, radix: uint) -> ~str;
261 }
262
263 /// A generic trait for converting a string with a radix (base) to a value
264 pub trait FromStrRadix {
265 fn from_str_radix(str: &str, radix: uint) -> Option<Self>;
266 }
267
268 /// A utility function that just calls FromStrRadix::from_str_radix.
269 pub fn from_str_radix<T: FromStrRadix>(str: &str, radix: uint) -> Option<T> {
270 FromStrRadix::from_str_radix(str, radix)
271 }
272
273 /// Helper function for testing numeric operations
274 #[cfg(test)]
275 pub fn test_num<T:Num + NumCast + Show>(ten: T, two: T) {
276 assert_eq!(ten.add(&two), cast(12).unwrap());
277 assert_eq!(ten.sub(&two), cast(8).unwrap());
278 assert_eq!(ten.mul(&two), cast(20).unwrap());
279 assert_eq!(ten.div(&two), cast(5).unwrap());
280 assert_eq!(ten.rem(&two), cast(0).unwrap());
281
282 assert_eq!(ten.add(&two), ten + two);
283 assert_eq!(ten.sub(&two), ten - two);
284 assert_eq!(ten.mul(&two), ten * two);
285 assert_eq!(ten.div(&two), ten / two);
286 assert_eq!(ten.rem(&two), ten % two);
287 }
288
289 #[cfg(test)]
290 mod tests {
291 use prelude::*;
292 use super::*;
293 use i8;
294 use i16;
295 use i32;
296 use i64;
297 use int;
298 use u8;
299 use u16;
300 use u32;
301 use u64;
302 use uint;
303
304 macro_rules! test_cast_20(
305 ($_20:expr) => ({
306 let _20 = $_20;
307
308 assert_eq!(20u, _20.to_uint().unwrap());
309 assert_eq!(20u8, _20.to_u8().unwrap());
310 assert_eq!(20u16, _20.to_u16().unwrap());
311 assert_eq!(20u32, _20.to_u32().unwrap());
312 assert_eq!(20u64, _20.to_u64().unwrap());
313 assert_eq!(20i, _20.to_int().unwrap());
314 assert_eq!(20i8, _20.to_i8().unwrap());
315 assert_eq!(20i16, _20.to_i16().unwrap());
316 assert_eq!(20i32, _20.to_i32().unwrap());
317 assert_eq!(20i64, _20.to_i64().unwrap());
318 assert_eq!(20f32, _20.to_f32().unwrap());
319 assert_eq!(20f64, _20.to_f64().unwrap());
320
321 assert_eq!(_20, NumCast::from(20u).unwrap());
322 assert_eq!(_20, NumCast::from(20u8).unwrap());
323 assert_eq!(_20, NumCast::from(20u16).unwrap());
324 assert_eq!(_20, NumCast::from(20u32).unwrap());
325 assert_eq!(_20, NumCast::from(20u64).unwrap());
326 assert_eq!(_20, NumCast::from(20i).unwrap());
327 assert_eq!(_20, NumCast::from(20i8).unwrap());
328 assert_eq!(_20, NumCast::from(20i16).unwrap());
329 assert_eq!(_20, NumCast::from(20i32).unwrap());
330 assert_eq!(_20, NumCast::from(20i64).unwrap());
331 assert_eq!(_20, NumCast::from(20f32).unwrap());
332 assert_eq!(_20, NumCast::from(20f64).unwrap());
333
334 assert_eq!(_20, cast(20u).unwrap());
335 assert_eq!(_20, cast(20u8).unwrap());
336 assert_eq!(_20, cast(20u16).unwrap());
337 assert_eq!(_20, cast(20u32).unwrap());
338 assert_eq!(_20, cast(20u64).unwrap());
339 assert_eq!(_20, cast(20i).unwrap());
340 assert_eq!(_20, cast(20i8).unwrap());
341 assert_eq!(_20, cast(20i16).unwrap());
342 assert_eq!(_20, cast(20i32).unwrap());
343 assert_eq!(_20, cast(20i64).unwrap());
344 assert_eq!(_20, cast(20f32).unwrap());
345 assert_eq!(_20, cast(20f64).unwrap());
346 })
347 )
348
349 #[test] fn test_u8_cast() { test_cast_20!(20u8) }
350 #[test] fn test_u16_cast() { test_cast_20!(20u16) }
351 #[test] fn test_u32_cast() { test_cast_20!(20u32) }
352 #[test] fn test_u64_cast() { test_cast_20!(20u64) }
353 #[test] fn test_uint_cast() { test_cast_20!(20u) }
354 #[test] fn test_i8_cast() { test_cast_20!(20i8) }
355 #[test] fn test_i16_cast() { test_cast_20!(20i16) }
356 #[test] fn test_i32_cast() { test_cast_20!(20i32) }
357 #[test] fn test_i64_cast() { test_cast_20!(20i64) }
358 #[test] fn test_int_cast() { test_cast_20!(20i) }
359 #[test] fn test_f32_cast() { test_cast_20!(20f32) }
360 #[test] fn test_f64_cast() { test_cast_20!(20f64) }
361
362 #[test]
363 fn test_cast_range_int_min() {
364 assert_eq!(int::MIN.to_int(), Some(int::MIN as int));
365 assert_eq!(int::MIN.to_i8(), None);
366 assert_eq!(int::MIN.to_i16(), None);
367 // int::MIN.to_i32() is word-size specific
368 assert_eq!(int::MIN.to_i64(), Some(int::MIN as i64));
369 assert_eq!(int::MIN.to_uint(), None);
370 assert_eq!(int::MIN.to_u8(), None);
371 assert_eq!(int::MIN.to_u16(), None);
372 assert_eq!(int::MIN.to_u32(), None);
373 assert_eq!(int::MIN.to_u64(), None);
374
375 #[cfg(target_word_size = "32")]
376 fn check_word_size() {
377 assert_eq!(int::MIN.to_i32(), Some(int::MIN as i32));
378 }
379
380 #[cfg(target_word_size = "64")]
381 fn check_word_size() {
382 assert_eq!(int::MIN.to_i32(), None);
383 }
384
385 check_word_size();
386 }
387
388 #[test]
389 fn test_cast_range_i8_min() {
390 assert_eq!(i8::MIN.to_int(), Some(i8::MIN as int));
391 assert_eq!(i8::MIN.to_i8(), Some(i8::MIN as i8));
392 assert_eq!(i8::MIN.to_i16(), Some(i8::MIN as i16));
393 assert_eq!(i8::MIN.to_i32(), Some(i8::MIN as i32));
394 assert_eq!(i8::MIN.to_i64(), Some(i8::MIN as i64));
395 assert_eq!(i8::MIN.to_uint(), None);
396 assert_eq!(i8::MIN.to_u8(), None);
397 assert_eq!(i8::MIN.to_u16(), None);
398 assert_eq!(i8::MIN.to_u32(), None);
399 assert_eq!(i8::MIN.to_u64(), None);
400 }
401
402 #[test]
403 fn test_cast_range_i16_min() {
404 assert_eq!(i16::MIN.to_int(), Some(i16::MIN as int));
405 assert_eq!(i16::MIN.to_i8(), None);
406 assert_eq!(i16::MIN.to_i16(), Some(i16::MIN as i16));
407 assert_eq!(i16::MIN.to_i32(), Some(i16::MIN as i32));
408 assert_eq!(i16::MIN.to_i64(), Some(i16::MIN as i64));
409 assert_eq!(i16::MIN.to_uint(), None);
410 assert_eq!(i16::MIN.to_u8(), None);
411 assert_eq!(i16::MIN.to_u16(), None);
412 assert_eq!(i16::MIN.to_u32(), None);
413 assert_eq!(i16::MIN.to_u64(), None);
414 }
415
416 #[test]
417 fn test_cast_range_i32_min() {
418 assert_eq!(i32::MIN.to_int(), Some(i32::MIN as int));
419 assert_eq!(i32::MIN.to_i8(), None);
420 assert_eq!(i32::MIN.to_i16(), None);
421 assert_eq!(i32::MIN.to_i32(), Some(i32::MIN as i32));
422 assert_eq!(i32::MIN.to_i64(), Some(i32::MIN as i64));
423 assert_eq!(i32::MIN.to_uint(), None);
424 assert_eq!(i32::MIN.to_u8(), None);
425 assert_eq!(i32::MIN.to_u16(), None);
426 assert_eq!(i32::MIN.to_u32(), None);
427 assert_eq!(i32::MIN.to_u64(), None);
428 }
429
430 #[test]
431 fn test_cast_range_i64_min() {
432 // i64::MIN.to_int() is word-size specific
433 assert_eq!(i64::MIN.to_i8(), None);
434 assert_eq!(i64::MIN.to_i16(), None);
435 assert_eq!(i64::MIN.to_i32(), None);
436 assert_eq!(i64::MIN.to_i64(), Some(i64::MIN as i64));
437 assert_eq!(i64::MIN.to_uint(), None);
438 assert_eq!(i64::MIN.to_u8(), None);
439 assert_eq!(i64::MIN.to_u16(), None);
440 assert_eq!(i64::MIN.to_u32(), None);
441 assert_eq!(i64::MIN.to_u64(), None);
442
443 #[cfg(target_word_size = "32")]
444 fn check_word_size() {
445 assert_eq!(i64::MIN.to_int(), None);
446 }
447
448 #[cfg(target_word_size = "64")]
449 fn check_word_size() {
450 assert_eq!(i64::MIN.to_int(), Some(i64::MIN as int));
451 }
452
453 check_word_size();
454 }
455
456 #[test]
457 fn test_cast_range_int_max() {
458 assert_eq!(int::MAX.to_int(), Some(int::MAX as int));
459 assert_eq!(int::MAX.to_i8(), None);
460 assert_eq!(int::MAX.to_i16(), None);
461 // int::MAX.to_i32() is word-size specific
462 assert_eq!(int::MAX.to_i64(), Some(int::MAX as i64));
463 assert_eq!(int::MAX.to_u8(), None);
464 assert_eq!(int::MAX.to_u16(), None);
465 // int::MAX.to_u32() is word-size specific
466 assert_eq!(int::MAX.to_u64(), Some(int::MAX as u64));
467
468 #[cfg(target_word_size = "32")]
469 fn check_word_size() {
470 assert_eq!(int::MAX.to_i32(), Some(int::MAX as i32));
471 assert_eq!(int::MAX.to_u32(), Some(int::MAX as u32));
472 }
473
474 #[cfg(target_word_size = "64")]
475 fn check_word_size() {
476 assert_eq!(int::MAX.to_i32(), None);
477 assert_eq!(int::MAX.to_u32(), None);
478 }
479
480 check_word_size();
481 }
482
483 #[test]
484 fn test_cast_range_i8_max() {
485 assert_eq!(i8::MAX.to_int(), Some(i8::MAX as int));
486 assert_eq!(i8::MAX.to_i8(), Some(i8::MAX as i8));
487 assert_eq!(i8::MAX.to_i16(), Some(i8::MAX as i16));
488 assert_eq!(i8::MAX.to_i32(), Some(i8::MAX as i32));
489 assert_eq!(i8::MAX.to_i64(), Some(i8::MAX as i64));
490 assert_eq!(i8::MAX.to_uint(), Some(i8::MAX as uint));
491 assert_eq!(i8::MAX.to_u8(), Some(i8::MAX as u8));
492 assert_eq!(i8::MAX.to_u16(), Some(i8::MAX as u16));
493 assert_eq!(i8::MAX.to_u32(), Some(i8::MAX as u32));
494 assert_eq!(i8::MAX.to_u64(), Some(i8::MAX as u64));
495 }
496
497 #[test]
498 fn test_cast_range_i16_max() {
499 assert_eq!(i16::MAX.to_int(), Some(i16::MAX as int));
500 assert_eq!(i16::MAX.to_i8(), None);
501 assert_eq!(i16::MAX.to_i16(), Some(i16::MAX as i16));
502 assert_eq!(i16::MAX.to_i32(), Some(i16::MAX as i32));
503 assert_eq!(i16::MAX.to_i64(), Some(i16::MAX as i64));
504 assert_eq!(i16::MAX.to_uint(), Some(i16::MAX as uint));
505 assert_eq!(i16::MAX.to_u8(), None);
506 assert_eq!(i16::MAX.to_u16(), Some(i16::MAX as u16));
507 assert_eq!(i16::MAX.to_u32(), Some(i16::MAX as u32));
508 assert_eq!(i16::MAX.to_u64(), Some(i16::MAX as u64));
509 }
510
511 #[test]
512 fn test_cast_range_i32_max() {
513 assert_eq!(i32::MAX.to_int(), Some(i32::MAX as int));
514 assert_eq!(i32::MAX.to_i8(), None);
515 assert_eq!(i32::MAX.to_i16(), None);
516 assert_eq!(i32::MAX.to_i32(), Some(i32::MAX as i32));
517 assert_eq!(i32::MAX.to_i64(), Some(i32::MAX as i64));
518 assert_eq!(i32::MAX.to_uint(), Some(i32::MAX as uint));
519 assert_eq!(i32::MAX.to_u8(), None);
520 assert_eq!(i32::MAX.to_u16(), None);
521 assert_eq!(i32::MAX.to_u32(), Some(i32::MAX as u32));
522 assert_eq!(i32::MAX.to_u64(), Some(i32::MAX as u64));
523 }
524
525 #[test]
526 fn test_cast_range_i64_max() {
527 // i64::MAX.to_int() is word-size specific
528 assert_eq!(i64::MAX.to_i8(), None);
529 assert_eq!(i64::MAX.to_i16(), None);
530 assert_eq!(i64::MAX.to_i32(), None);
531 assert_eq!(i64::MAX.to_i64(), Some(i64::MAX as i64));
532 // i64::MAX.to_uint() is word-size specific
533 assert_eq!(i64::MAX.to_u8(), None);
534 assert_eq!(i64::MAX.to_u16(), None);
535 assert_eq!(i64::MAX.to_u32(), None);
536 assert_eq!(i64::MAX.to_u64(), Some(i64::MAX as u64));
537
538 #[cfg(target_word_size = "32")]
539 fn check_word_size() {
540 assert_eq!(i64::MAX.to_int(), None);
541 assert_eq!(i64::MAX.to_uint(), None);
542 }
543
544 #[cfg(target_word_size = "64")]
545 fn check_word_size() {
546 assert_eq!(i64::MAX.to_int(), Some(i64::MAX as int));
547 assert_eq!(i64::MAX.to_uint(), Some(i64::MAX as uint));
548 }
549
550 check_word_size();
551 }
552
553 #[test]
554 fn test_cast_range_uint_min() {
555 assert_eq!(uint::MIN.to_int(), Some(uint::MIN as int));
556 assert_eq!(uint::MIN.to_i8(), Some(uint::MIN as i8));
557 assert_eq!(uint::MIN.to_i16(), Some(uint::MIN as i16));
558 assert_eq!(uint::MIN.to_i32(), Some(uint::MIN as i32));
559 assert_eq!(uint::MIN.to_i64(), Some(uint::MIN as i64));
560 assert_eq!(uint::MIN.to_uint(), Some(uint::MIN as uint));
561 assert_eq!(uint::MIN.to_u8(), Some(uint::MIN as u8));
562 assert_eq!(uint::MIN.to_u16(), Some(uint::MIN as u16));
563 assert_eq!(uint::MIN.to_u32(), Some(uint::MIN as u32));
564 assert_eq!(uint::MIN.to_u64(), Some(uint::MIN as u64));
565 }
566
567 #[test]
568 fn test_cast_range_u8_min() {
569 assert_eq!(u8::MIN.to_int(), Some(u8::MIN as int));
570 assert_eq!(u8::MIN.to_i8(), Some(u8::MIN as i8));
571 assert_eq!(u8::MIN.to_i16(), Some(u8::MIN as i16));
572 assert_eq!(u8::MIN.to_i32(), Some(u8::MIN as i32));
573 assert_eq!(u8::MIN.to_i64(), Some(u8::MIN as i64));
574 assert_eq!(u8::MIN.to_uint(), Some(u8::MIN as uint));
575 assert_eq!(u8::MIN.to_u8(), Some(u8::MIN as u8));
576 assert_eq!(u8::MIN.to_u16(), Some(u8::MIN as u16));
577 assert_eq!(u8::MIN.to_u32(), Some(u8::MIN as u32));
578 assert_eq!(u8::MIN.to_u64(), Some(u8::MIN as u64));
579 }
580
581 #[test]
582 fn test_cast_range_u16_min() {
583 assert_eq!(u16::MIN.to_int(), Some(u16::MIN as int));
584 assert_eq!(u16::MIN.to_i8(), Some(u16::MIN as i8));
585 assert_eq!(u16::MIN.to_i16(), Some(u16::MIN as i16));
586 assert_eq!(u16::MIN.to_i32(), Some(u16::MIN as i32));
587 assert_eq!(u16::MIN.to_i64(), Some(u16::MIN as i64));
588 assert_eq!(u16::MIN.to_uint(), Some(u16::MIN as uint));
589 assert_eq!(u16::MIN.to_u8(), Some(u16::MIN as u8));
590 assert_eq!(u16::MIN.to_u16(), Some(u16::MIN as u16));
591 assert_eq!(u16::MIN.to_u32(), Some(u16::MIN as u32));
592 assert_eq!(u16::MIN.to_u64(), Some(u16::MIN as u64));
593 }
594
595 #[test]
596 fn test_cast_range_u32_min() {
597 assert_eq!(u32::MIN.to_int(), Some(u32::MIN as int));
598 assert_eq!(u32::MIN.to_i8(), Some(u32::MIN as i8));
599 assert_eq!(u32::MIN.to_i16(), Some(u32::MIN as i16));
600 assert_eq!(u32::MIN.to_i32(), Some(u32::MIN as i32));
601 assert_eq!(u32::MIN.to_i64(), Some(u32::MIN as i64));
602 assert_eq!(u32::MIN.to_uint(), Some(u32::MIN as uint));
603 assert_eq!(u32::MIN.to_u8(), Some(u32::MIN as u8));
604 assert_eq!(u32::MIN.to_u16(), Some(u32::MIN as u16));
605 assert_eq!(u32::MIN.to_u32(), Some(u32::MIN as u32));
606 assert_eq!(u32::MIN.to_u64(), Some(u32::MIN as u64));
607 }
608
609 #[test]
610 fn test_cast_range_u64_min() {
611 assert_eq!(u64::MIN.to_int(), Some(u64::MIN as int));
612 assert_eq!(u64::MIN.to_i8(), Some(u64::MIN as i8));
613 assert_eq!(u64::MIN.to_i16(), Some(u64::MIN as i16));
614 assert_eq!(u64::MIN.to_i32(), Some(u64::MIN as i32));
615 assert_eq!(u64::MIN.to_i64(), Some(u64::MIN as i64));
616 assert_eq!(u64::MIN.to_uint(), Some(u64::MIN as uint));
617 assert_eq!(u64::MIN.to_u8(), Some(u64::MIN as u8));
618 assert_eq!(u64::MIN.to_u16(), Some(u64::MIN as u16));
619 assert_eq!(u64::MIN.to_u32(), Some(u64::MIN as u32));
620 assert_eq!(u64::MIN.to_u64(), Some(u64::MIN as u64));
621 }
622
623 #[test]
624 fn test_cast_range_uint_max() {
625 assert_eq!(uint::MAX.to_int(), None);
626 assert_eq!(uint::MAX.to_i8(), None);
627 assert_eq!(uint::MAX.to_i16(), None);
628 assert_eq!(uint::MAX.to_i32(), None);
629 // uint::MAX.to_i64() is word-size specific
630 assert_eq!(uint::MAX.to_u8(), None);
631 assert_eq!(uint::MAX.to_u16(), None);
632 // uint::MAX.to_u32() is word-size specific
633 assert_eq!(uint::MAX.to_u64(), Some(uint::MAX as u64));
634
635 #[cfg(target_word_size = "32")]
636 fn check_word_size() {
637 assert_eq!(uint::MAX.to_u32(), Some(uint::MAX as u32));
638 assert_eq!(uint::MAX.to_i64(), Some(uint::MAX as i64));
639 }
640
641 #[cfg(target_word_size = "64")]
642 fn check_word_size() {
643 assert_eq!(uint::MAX.to_u32(), None);
644 assert_eq!(uint::MAX.to_i64(), None);
645 }
646
647 check_word_size();
648 }
649
650 #[test]
651 fn test_cast_range_u8_max() {
652 assert_eq!(u8::MAX.to_int(), Some(u8::MAX as int));
653 assert_eq!(u8::MAX.to_i8(), None);
654 assert_eq!(u8::MAX.to_i16(), Some(u8::MAX as i16));
655 assert_eq!(u8::MAX.to_i32(), Some(u8::MAX as i32));
656 assert_eq!(u8::MAX.to_i64(), Some(u8::MAX as i64));
657 assert_eq!(u8::MAX.to_uint(), Some(u8::MAX as uint));
658 assert_eq!(u8::MAX.to_u8(), Some(u8::MAX as u8));
659 assert_eq!(u8::MAX.to_u16(), Some(u8::MAX as u16));
660 assert_eq!(u8::MAX.to_u32(), Some(u8::MAX as u32));
661 assert_eq!(u8::MAX.to_u64(), Some(u8::MAX as u64));
662 }
663
664 #[test]
665 fn test_cast_range_u16_max() {
666 assert_eq!(u16::MAX.to_int(), Some(u16::MAX as int));
667 assert_eq!(u16::MAX.to_i8(), None);
668 assert_eq!(u16::MAX.to_i16(), None);
669 assert_eq!(u16::MAX.to_i32(), Some(u16::MAX as i32));
670 assert_eq!(u16::MAX.to_i64(), Some(u16::MAX as i64));
671 assert_eq!(u16::MAX.to_uint(), Some(u16::MAX as uint));
672 assert_eq!(u16::MAX.to_u8(), None);
673 assert_eq!(u16::MAX.to_u16(), Some(u16::MAX as u16));
674 assert_eq!(u16::MAX.to_u32(), Some(u16::MAX as u32));
675 assert_eq!(u16::MAX.to_u64(), Some(u16::MAX as u64));
676 }
677
678 #[test]
679 fn test_cast_range_u32_max() {
680 // u32::MAX.to_int() is word-size specific
681 assert_eq!(u32::MAX.to_i8(), None);
682 assert_eq!(u32::MAX.to_i16(), None);
683 assert_eq!(u32::MAX.to_i32(), None);
684 assert_eq!(u32::MAX.to_i64(), Some(u32::MAX as i64));
685 assert_eq!(u32::MAX.to_uint(), Some(u32::MAX as uint));
686 assert_eq!(u32::MAX.to_u8(), None);
687 assert_eq!(u32::MAX.to_u16(), None);
688 assert_eq!(u32::MAX.to_u32(), Some(u32::MAX as u32));
689 assert_eq!(u32::MAX.to_u64(), Some(u32::MAX as u64));
690
691 #[cfg(target_word_size = "32")]
692 fn check_word_size() {
693 assert_eq!(u32::MAX.to_int(), None);
694 }
695
696 #[cfg(target_word_size = "64")]
697 fn check_word_size() {
698 assert_eq!(u32::MAX.to_int(), Some(u32::MAX as int));
699 }
700
701 check_word_size();
702 }
703
704 #[test]
705 fn test_cast_range_u64_max() {
706 assert_eq!(u64::MAX.to_int(), None);
707 assert_eq!(u64::MAX.to_i8(), None);
708 assert_eq!(u64::MAX.to_i16(), None);
709 assert_eq!(u64::MAX.to_i32(), None);
710 assert_eq!(u64::MAX.to_i64(), None);
711 // u64::MAX.to_uint() is word-size specific
712 assert_eq!(u64::MAX.to_u8(), None);
713 assert_eq!(u64::MAX.to_u16(), None);
714 assert_eq!(u64::MAX.to_u32(), None);
715 assert_eq!(u64::MAX.to_u64(), Some(u64::MAX as u64));
716
717 #[cfg(target_word_size = "32")]
718 fn check_word_size() {
719 assert_eq!(u64::MAX.to_uint(), None);
720 }
721
722 #[cfg(target_word_size = "64")]
723 fn check_word_size() {
724 assert_eq!(u64::MAX.to_uint(), Some(u64::MAX as uint));
725 }
726
727 check_word_size();
728 }
729
730 #[test]
731 fn test_saturating_add_uint() {
732 use uint::MAX;
733 assert_eq!(3u.saturating_add(5u), 8u);
734 assert_eq!(3u.saturating_add(MAX-1), MAX);
735 assert_eq!(MAX.saturating_add(MAX), MAX);
736 assert_eq!((MAX-2).saturating_add(1), MAX-1);
737 }
738
739 #[test]
740 fn test_saturating_sub_uint() {
741 use uint::MAX;
742 assert_eq!(5u.saturating_sub(3u), 2u);
743 assert_eq!(3u.saturating_sub(5u), 0u);
744 assert_eq!(0u.saturating_sub(1u), 0u);
745 assert_eq!((MAX-1).saturating_sub(MAX), 0);
746 }
747
748 #[test]
749 fn test_saturating_add_int() {
750 use int::{MIN,MAX};
751 assert_eq!(3i.saturating_add(5i), 8i);
752 assert_eq!(3i.saturating_add(MAX-1), MAX);
753 assert_eq!(MAX.saturating_add(MAX), MAX);
754 assert_eq!((MAX-2).saturating_add(1), MAX-1);
755 assert_eq!(3i.saturating_add(-5i), -2i);
756 assert_eq!(MIN.saturating_add(-1i), MIN);
757 assert_eq!((-2i).saturating_add(-MAX), MIN);
758 }
759
760 #[test]
761 fn test_saturating_sub_int() {
762 use int::{MIN,MAX};
763 assert_eq!(3i.saturating_sub(5i), -2i);
764 assert_eq!(MIN.saturating_sub(1i), MIN);
765 assert_eq!((-2i).saturating_sub(MAX), MIN);
766 assert_eq!(3i.saturating_sub(-5i), 8i);
767 assert_eq!(3i.saturating_sub(-(MAX-1)), MAX);
768 assert_eq!(MAX.saturating_sub(-MAX), MAX);
769 assert_eq!((MAX-2).saturating_sub(-1), MAX-1);
770 }
771
772 #[test]
773 fn test_checked_add() {
774 let five_less = uint::MAX - 5;
775 assert_eq!(five_less.checked_add(&0), Some(uint::MAX - 5));
776 assert_eq!(five_less.checked_add(&1), Some(uint::MAX - 4));
777 assert_eq!(five_less.checked_add(&2), Some(uint::MAX - 3));
778 assert_eq!(five_less.checked_add(&3), Some(uint::MAX - 2));
779 assert_eq!(five_less.checked_add(&4), Some(uint::MAX - 1));
780 assert_eq!(five_less.checked_add(&5), Some(uint::MAX));
781 assert_eq!(five_less.checked_add(&6), None);
782 assert_eq!(five_less.checked_add(&7), None);
783 }
784
785 #[test]
786 fn test_checked_sub() {
787 assert_eq!(5u.checked_sub(&0), Some(5));
788 assert_eq!(5u.checked_sub(&1), Some(4));
789 assert_eq!(5u.checked_sub(&2), Some(3));
790 assert_eq!(5u.checked_sub(&3), Some(2));
791 assert_eq!(5u.checked_sub(&4), Some(1));
792 assert_eq!(5u.checked_sub(&5), Some(0));
793 assert_eq!(5u.checked_sub(&6), None);
794 assert_eq!(5u.checked_sub(&7), None);
795 }
796
797 #[test]
798 fn test_checked_mul() {
799 let third = uint::MAX / 3;
800 assert_eq!(third.checked_mul(&0), Some(0));
801 assert_eq!(third.checked_mul(&1), Some(third));
802 assert_eq!(third.checked_mul(&2), Some(third * 2));
803 assert_eq!(third.checked_mul(&3), Some(third * 3));
804 assert_eq!(third.checked_mul(&4), None);
805 }
806
807 macro_rules! test_next_power_of_two(
808 ($test_name:ident, $T:ident) => (
809 fn $test_name() {
810 #![test]
811 assert_eq!(next_power_of_two::<$T>(0), 0);
812 let mut next_power = 1;
813 for i in range::<$T>(1, 40) {
814 assert_eq!(next_power_of_two(i), next_power);
815 if i == next_power { next_power *= 2 }
816 }
817 }
818 )
819 )
820
821 test_next_power_of_two!(test_next_power_of_two_u8, u8)
822 test_next_power_of_two!(test_next_power_of_two_u16, u16)
823 test_next_power_of_two!(test_next_power_of_two_u32, u32)
824 test_next_power_of_two!(test_next_power_of_two_u64, u64)
825 test_next_power_of_two!(test_next_power_of_two_uint, uint)
826
827 macro_rules! test_checked_next_power_of_two(
828 ($test_name:ident, $T:ident) => (
829 fn $test_name() {
830 #![test]
831 assert_eq!(checked_next_power_of_two::<$T>(0), None);
832 let mut next_power = 1;
833 for i in range::<$T>(1, 40) {
834 assert_eq!(checked_next_power_of_two(i), Some(next_power));
835 if i == next_power { next_power *= 2 }
836 }
837 assert!(checked_next_power_of_two::<$T>($T::MAX / 2).is_some());
838 assert_eq!(checked_next_power_of_two::<$T>($T::MAX - 1), None);
839 assert_eq!(checked_next_power_of_two::<$T>($T::MAX), None);
840 }
841 )
842 )
843
844 test_checked_next_power_of_two!(test_checked_next_power_of_two_u8, u8)
845 test_checked_next_power_of_two!(test_checked_next_power_of_two_u16, u16)
846 test_checked_next_power_of_two!(test_checked_next_power_of_two_u32, u32)
847 test_checked_next_power_of_two!(test_checked_next_power_of_two_u64, u64)
848 test_checked_next_power_of_two!(test_checked_next_power_of_two_uint, uint)
849
850 #[deriving(Eq, Show)]
851 struct Value { x: int }
852
853 impl ToPrimitive for Value {
854 fn to_i64(&self) -> Option<i64> { self.x.to_i64() }
855 fn to_u64(&self) -> Option<u64> { self.x.to_u64() }
856 }
857
858 impl FromPrimitive for Value {
859 fn from_i64(n: i64) -> Option<Value> { Some(Value { x: n as int }) }
860 fn from_u64(n: u64) -> Option<Value> { Some(Value { x: n as int }) }
861 }
862
863 #[test]
864 fn test_to_primitive() {
865 let value = Value { x: 5 };
866 assert_eq!(value.to_int(), Some(5));
867 assert_eq!(value.to_i8(), Some(5));
868 assert_eq!(value.to_i16(), Some(5));
869 assert_eq!(value.to_i32(), Some(5));
870 assert_eq!(value.to_i64(), Some(5));
871 assert_eq!(value.to_uint(), Some(5));
872 assert_eq!(value.to_u8(), Some(5));
873 assert_eq!(value.to_u16(), Some(5));
874 assert_eq!(value.to_u32(), Some(5));
875 assert_eq!(value.to_u64(), Some(5));
876 assert_eq!(value.to_f32(), Some(5f32));
877 assert_eq!(value.to_f64(), Some(5f64));
878 }
879
880 #[test]
881 fn test_from_primitive() {
882 assert_eq!(from_int(5), Some(Value { x: 5 }));
883 assert_eq!(from_i8(5), Some(Value { x: 5 }));
884 assert_eq!(from_i16(5), Some(Value { x: 5 }));
885 assert_eq!(from_i32(5), Some(Value { x: 5 }));
886 assert_eq!(from_i64(5), Some(Value { x: 5 }));
887 assert_eq!(from_uint(5), Some(Value { x: 5 }));
888 assert_eq!(from_u8(5), Some(Value { x: 5 }));
889 assert_eq!(from_u16(5), Some(Value { x: 5 }));
890 assert_eq!(from_u32(5), Some(Value { x: 5 }));
891 assert_eq!(from_u64(5), Some(Value { x: 5 }));
892 assert_eq!(from_f32(5f32), Some(Value { x: 5 }));
893 assert_eq!(from_f64(5f64), Some(Value { x: 5 }));
894 }
895
896 #[test]
897 fn test_pow() {
898 fn naive_pow<T: One + Mul<T, T>>(base: T, exp: uint) -> T {
899 range(0, exp).fold(one::<T>(), |acc, _| acc * base)
900 }
901 macro_rules! assert_pow(
902 (($num:expr, $exp:expr) => $expected:expr) => {{
903 let result = pow($num, $exp);
904 assert_eq!(result, $expected);
905 assert_eq!(result, naive_pow($num, $exp));
906 }}
907 )
908 assert_pow!((3, 0 ) => 1);
909 assert_pow!((5, 1 ) => 5);
910 assert_pow!((-4, 2 ) => 16);
911 assert_pow!((0.5, 5 ) => 0.03125);
912 assert_pow!((8, 3 ) => 512);
913 assert_pow!((8.0, 5 ) => 32768.0);
914 assert_pow!((8.5, 5 ) => 44370.53125);
915 assert_pow!((2u64, 50) => 1125899906842624);
916 }
917 }
918
919
920 #[cfg(test)]
921 mod bench {
922 extern crate test;
923 use self::test::Bencher;
924 use num;
925 use prelude::*;
926
927 #[bench]
928 fn bench_pow_function(b: &mut Bencher) {
929 let v = Vec::from_fn(1024, |n| n);
930 b.iter(|| {v.iter().fold(0, |old, new| num::pow(old, *new));});
931 }
932 }