lib.rs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  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 = "num-bigint")]
  68. pub use num_bigint::{BigInt, BigUint};
  69. #[cfg(feature = "num-rational")]
  70. pub use num_rational::Rational;
  71. #[cfg(all(feature = "num-rational", feature="num-bigint"))]
  72. pub use num_rational::BigRational;
  73. #[cfg(feature = "num-complex")]
  74. pub use num_complex::Complex;
  75. pub use num_integer::Integer;
  76. pub use num_iter::{range, range_inclusive, range_step, range_step_inclusive};
  77. pub use num_traits::{Num, Zero, One, Signed, Unsigned, Bounded,
  78. Saturating, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv,
  79. PrimInt, Float, ToPrimitive, FromPrimitive, NumCast, cast};
  80. use std::ops::{Mul};
  81. #[cfg(feature = "num-bigint")]
  82. pub use num_bigint as bigint;
  83. #[cfg(feature = "num-complex")]
  84. pub use num_complex as complex;
  85. pub use num_integer as integer;
  86. pub use num_iter as iter;
  87. pub use num_traits as traits;
  88. #[cfg(feature = "num-rational")]
  89. pub use num_rational as rational;
  90. /// Returns the additive identity, `0`.
  91. #[inline(always)] pub fn zero<T: Zero>() -> T { Zero::zero() }
  92. /// Returns the multiplicative identity, `1`.
  93. #[inline(always)] pub fn one<T: One>() -> T { One::one() }
  94. /// Computes the absolute value.
  95. ///
  96. /// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`
  97. ///
  98. /// For signed integers, `::MIN` will be returned if the number is `::MIN`.
  99. #[inline(always)]
  100. pub fn abs<T: Signed>(value: T) -> T {
  101. value.abs()
  102. }
  103. /// The positive difference of two numbers.
  104. ///
  105. /// Returns zero if `x` is less than or equal to `y`, otherwise the difference
  106. /// between `x` and `y` is returned.
  107. #[inline(always)]
  108. pub fn abs_sub<T: Signed>(x: T, y: T) -> T {
  109. x.abs_sub(&y)
  110. }
  111. /// Returns the sign of the number.
  112. ///
  113. /// For `f32` and `f64`:
  114. ///
  115. /// * `1.0` if the number is positive, `+0.0` or `INFINITY`
  116. /// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
  117. /// * `NaN` if the number is `NaN`
  118. ///
  119. /// For signed integers:
  120. ///
  121. /// * `0` if the number is zero
  122. /// * `1` if the number is positive
  123. /// * `-1` if the number is negative
  124. #[inline(always)] pub fn signum<T: Signed>(value: T) -> T { value.signum() }
  125. /// Raises a value to the power of exp, using exponentiation by squaring.
  126. ///
  127. /// # Example
  128. ///
  129. /// ```rust
  130. /// use num;
  131. ///
  132. /// assert_eq!(num::pow(2i8, 4), 16);
  133. /// assert_eq!(num::pow(6u8, 3), 216);
  134. /// ```
  135. #[inline]
  136. pub fn pow<T: Clone + One + Mul<T, Output = T>>(mut base: T, mut exp: usize) -> T {
  137. if exp == 0 { return T::one() }
  138. while exp & 1 == 0 {
  139. base = base.clone() * base;
  140. exp >>= 1;
  141. }
  142. if exp == 1 { return base }
  143. let mut acc = base.clone();
  144. while exp > 1 {
  145. exp >>= 1;
  146. base = base.clone() * base;
  147. if exp & 1 == 1 {
  148. acc = acc * base.clone();
  149. }
  150. }
  151. acc
  152. }
  153. /// Raises a value to the power of exp, returning `None` if an overflow occurred.
  154. ///
  155. /// Otherwise same as the `pow` function.
  156. ///
  157. /// # Example
  158. ///
  159. /// ```rust
  160. /// use num;
  161. ///
  162. /// assert_eq!(num::checked_pow(2i8, 4), Some(16));
  163. /// assert_eq!(num::checked_pow(7i8, 8), None);
  164. /// assert_eq!(num::checked_pow(7u32, 8), Some(5_764_801));
  165. /// ```
  166. #[inline]
  167. pub fn checked_pow<T: Clone + One + CheckedMul>(mut base: T, mut exp: usize) -> Option<T> {
  168. if exp == 0 { return Some(T::one()) }
  169. macro_rules! optry {
  170. ( $ expr : expr ) => {
  171. if let Some(val) = $expr { val } else { return None }
  172. }
  173. }
  174. while exp & 1 == 0 {
  175. base = optry!(base.checked_mul(&base));
  176. exp >>= 1;
  177. }
  178. if exp == 1 { return Some(base) }
  179. let mut acc = base.clone();
  180. while exp > 1 {
  181. exp >>= 1;
  182. base = optry!(base.checked_mul(&base));
  183. if exp & 1 == 1 {
  184. acc = optry!(acc.checked_mul(&base));
  185. }
  186. }
  187. Some(acc)
  188. }