lib.rs 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. // Copyright 2014-2016 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. //! A collection of numeric types and traits for Rust.
  11. //!
  12. //! This includes new types for big integers, rationals, and complex numbers,
  13. //! new traits for generic programming on numeric properties like `Integer`,
  14. //! and generic range iterators.
  15. //!
  16. //! ## Example
  17. //!
  18. //! This example uses the BigRational type and [Newton's method][newt] to
  19. //! approximate a square root to arbitrary precision:
  20. //!
  21. //! ```
  22. //! extern crate num;
  23. //! # #[cfg(all(feature = "bigint", feature="rational"))]
  24. //! # mod test {
  25. //!
  26. //! use num::FromPrimitive;
  27. //! use num::bigint::BigInt;
  28. //! use num::rational::{Ratio, BigRational};
  29. //!
  30. //! # pub
  31. //! fn approx_sqrt(number: u64, iterations: usize) -> BigRational {
  32. //! let start: Ratio<BigInt> = Ratio::from_integer(FromPrimitive::from_u64(number).unwrap());
  33. //! let mut approx = start.clone();
  34. //!
  35. //! for _ in 0..iterations {
  36. //! approx = (&approx + (&start / &approx)) /
  37. //! Ratio::from_integer(FromPrimitive::from_u64(2).unwrap());
  38. //! }
  39. //!
  40. //! approx
  41. //! }
  42. //! # }
  43. //! # #[cfg(not(all(feature = "bigint", feature="rational")))]
  44. //! # mod test { pub fn approx_sqrt(n: u64, _: usize) -> u64 { n } }
  45. //! # use test::approx_sqrt;
  46. //!
  47. //! fn main() {
  48. //! println!("{}", approx_sqrt(10, 4)); // prints 4057691201/1283082416
  49. //! }
  50. //!
  51. //! ```
  52. //!
  53. //! [newt]: https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method
  54. #![doc(html_logo_url = "http://rust-num.github.io/num/rust-logo-128x128-blk-v2.png",
  55. html_favicon_url = "http://rust-num.github.io/num/favicon.ico",
  56. html_root_url = "http://rust-num.github.io/num/",
  57. html_playground_url = "http://play.rust-lang.org/")]
  58. pub extern crate num_traits;
  59. pub extern crate num_integer;
  60. pub extern crate num_iter;
  61. #[cfg(feature = "num-complex")]
  62. pub extern crate num_complex;
  63. #[cfg(feature = "num-bigint")]
  64. pub extern crate num_bigint;
  65. #[cfg(feature = "num-rational")]
  66. pub extern crate num_rational;
  67. #[cfg(feature = "rustc-serialize")]
  68. extern crate rustc_serialize;
  69. // Some of the tests of non-RNG-based functionality are randomized using the
  70. // RNG-based functionality, so the RNG-based functionality needs to be enabled
  71. // for tests.
  72. #[cfg(any(feature = "rand", all(feature = "bigint", test)))]
  73. extern crate rand;
  74. #[cfg(feature = "serde")]
  75. extern crate serde;
  76. #[cfg(feature = "num-bigint")]
  77. pub use num_bigint::{BigInt, BigUint};
  78. #[cfg(feature = "num-rational")]
  79. pub use num_rational::Rational;
  80. #[cfg(all(feature = "num-rational", feature="num-bigint"))]
  81. pub use num_rational::BigRational;
  82. #[cfg(feature = "num-complex")]
  83. pub use num_complex::Complex;
  84. pub use num_integer::Integer;
  85. pub use num_iter::{range, range_inclusive, range_step, range_step_inclusive};
  86. pub use num_traits::{Num, Zero, One, Signed, Unsigned, Bounded,
  87. Saturating, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv,
  88. PrimInt, Float, ToPrimitive, FromPrimitive, NumCast, cast};
  89. use std::ops::{Mul};
  90. #[cfg(feature = "num-bigint")]
  91. pub use num_bigint as bigint;
  92. #[cfg(feature = "num-complex")]
  93. pub use num_complex as complex;
  94. pub use num_integer as integer;
  95. pub use num_iter as iter;
  96. pub use num_traits as traits;
  97. #[cfg(feature = "num-rational")]
  98. pub use num_rational as rational;
  99. /// Returns the additive identity, `0`.
  100. #[inline(always)] pub fn zero<T: Zero>() -> T { Zero::zero() }
  101. /// Returns the multiplicative identity, `1`.
  102. #[inline(always)] pub fn one<T: One>() -> T { One::one() }
  103. /// Computes the absolute value.
  104. ///
  105. /// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`
  106. ///
  107. /// For signed integers, `::MIN` will be returned if the number is `::MIN`.
  108. #[inline(always)]
  109. pub fn abs<T: Signed>(value: T) -> T {
  110. value.abs()
  111. }
  112. /// The positive difference of two numbers.
  113. ///
  114. /// Returns zero if `x` is less than or equal to `y`, otherwise the difference
  115. /// between `x` and `y` is returned.
  116. #[inline(always)]
  117. pub fn abs_sub<T: Signed>(x: T, y: T) -> T {
  118. x.abs_sub(&y)
  119. }
  120. /// Returns the sign of the number.
  121. ///
  122. /// For `f32` and `f64`:
  123. ///
  124. /// * `1.0` if the number is positive, `+0.0` or `INFINITY`
  125. /// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
  126. /// * `NaN` if the number is `NaN`
  127. ///
  128. /// For signed integers:
  129. ///
  130. /// * `0` if the number is zero
  131. /// * `1` if the number is positive
  132. /// * `-1` if the number is negative
  133. #[inline(always)] pub fn signum<T: Signed>(value: T) -> T { value.signum() }
  134. /// Raises a value to the power of exp, using exponentiation by squaring.
  135. ///
  136. /// # Example
  137. ///
  138. /// ```rust
  139. /// use num;
  140. ///
  141. /// assert_eq!(num::pow(2i8, 4), 16);
  142. /// assert_eq!(num::pow(6u8, 3), 216);
  143. /// ```
  144. #[inline]
  145. pub fn pow<T: Clone + One + Mul<T, Output = T>>(mut base: T, mut exp: usize) -> T {
  146. if exp == 0 { return T::one() }
  147. while exp & 1 == 0 {
  148. base = base.clone() * base;
  149. exp >>= 1;
  150. }
  151. if exp == 1 { return base }
  152. let mut acc = base.clone();
  153. while exp > 1 {
  154. exp >>= 1;
  155. base = base.clone() * base;
  156. if exp & 1 == 1 {
  157. acc = acc * base.clone();
  158. }
  159. }
  160. acc
  161. }
  162. /// Raises a value to the power of exp, returning `None` if an overflow occurred.
  163. ///
  164. /// Otherwise same as the `pow` function.
  165. ///
  166. /// # Example
  167. ///
  168. /// ```rust
  169. /// use num;
  170. ///
  171. /// assert_eq!(num::checked_pow(2i8, 4), Some(16));
  172. /// assert_eq!(num::checked_pow(7i8, 8), None);
  173. /// assert_eq!(num::checked_pow(7u32, 8), Some(5_764_801));
  174. /// ```
  175. #[inline]
  176. pub fn checked_pow<T: Clone + One + CheckedMul>(mut base: T, mut exp: usize) -> Option<T> {
  177. if exp == 0 { return Some(T::one()) }
  178. macro_rules! optry {
  179. ( $ expr : expr ) => {
  180. if let Some(val) = $expr { val } else { return None }
  181. }
  182. }
  183. while exp & 1 == 0 {
  184. base = optry!(base.checked_mul(&base));
  185. exp >>= 1;
  186. }
  187. if exp == 1 { return Some(base) }
  188. let mut acc = base.clone();
  189. while exp > 1 {
  190. exp >>= 1;
  191. base = optry!(base.checked_mul(&base));
  192. if exp & 1 == 1 {
  193. acc = optry!(acc.checked_mul(&base));
  194. }
  195. }
  196. Some(acc)
  197. }