lib.rs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. // Copyright 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. //! Simple numerics.
  11. //!
  12. //! This crate contains arbitrary-sized integer, rational, and complex types.
  13. //!
  14. //! ## Example
  15. //!
  16. //! This example uses the BigRational type and [Newton's method][newt] to
  17. //! approximate a square root to arbitrary precision:
  18. //!
  19. //! ```
  20. //! extern crate num;
  21. //! # #[cfg(all(feature = "bigint", feature="rational"))]
  22. //! # pub mod test {
  23. //!
  24. //! use num::FromPrimitive;
  25. //! use num::bigint::BigInt;
  26. //! use num::rational::{Ratio, BigRational};
  27. //!
  28. //! fn approx_sqrt(number: u64, iterations: usize) -> BigRational {
  29. //! let start: Ratio<BigInt> = Ratio::from_integer(FromPrimitive::from_u64(number).unwrap());
  30. //! let mut approx = start.clone();
  31. //!
  32. //! for _ in 0..iterations {
  33. //! approx = (&approx + (&start / &approx)) /
  34. //! Ratio::from_integer(FromPrimitive::from_u64(2).unwrap());
  35. //! }
  36. //!
  37. //! approx
  38. //! }
  39. //! # }
  40. //! # #[cfg(not(all(feature = "bigint", feature="rational")))]
  41. //! # fn approx_sqrt(n: u64, _: usize) -> u64 { n }
  42. //!
  43. //! fn main() {
  44. //! println!("{}", approx_sqrt(10, 4)); // prints 4057691201/1283082416
  45. //! }
  46. //!
  47. //! ```
  48. //!
  49. //! [newt]: https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method
  50. #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
  51. html_favicon_url = "http://www.rust-lang.org/favicon.ico",
  52. html_root_url = "http://doc.rust-lang.org/num/",
  53. html_playground_url = "http://play.rust-lang.org/")]
  54. #[cfg(feature = "rustc-serialize")]
  55. extern crate rustc_serialize;
  56. #[cfg(feature = "rand")]
  57. extern crate rand;
  58. #[cfg(feature = "bigint")]
  59. pub use bigint::{BigInt, BigUint};
  60. #[cfg(feature = "rational")]
  61. pub use rational::Rational;
  62. #[cfg(all(feature = "rational", feature="bigint"))]
  63. pub use rational::BigRational;
  64. #[cfg(feature = "complex")]
  65. pub use complex::Complex;
  66. pub use integer::Integer;
  67. pub use iter::{range, range_inclusive, range_step, range_step_inclusive};
  68. pub use traits::{Num, Zero, One, Signed, Unsigned, Bounded,
  69. Saturating, CheckedAdd, CheckedSub, CheckedMul, CheckedDiv,
  70. PrimInt, Float, ToPrimitive, FromPrimitive, NumCast, cast};
  71. #[cfg(test)] use std::hash;
  72. use std::ops::{Mul};
  73. #[cfg(feature = "bigint")]
  74. pub mod bigint;
  75. pub mod complex;
  76. pub mod integer;
  77. pub mod iter;
  78. pub mod traits;
  79. #[cfg(feature = "rational")]
  80. pub mod rational;
  81. /// Returns the additive identity, `0`.
  82. #[inline(always)] pub fn zero<T: Zero>() -> T { Zero::zero() }
  83. /// Returns the multiplicative identity, `1`.
  84. #[inline(always)] pub fn one<T: One>() -> T { One::one() }
  85. /// Computes the absolute value.
  86. ///
  87. /// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`
  88. ///
  89. /// For signed integers, `::MIN` will be returned if the number is `::MIN`.
  90. #[inline(always)]
  91. pub fn abs<T: Signed>(value: T) -> T {
  92. value.abs()
  93. }
  94. /// The positive difference of two numbers.
  95. ///
  96. /// Returns zero if `x` is less than or equal to `y`, otherwise the difference
  97. /// between `x` and `y` is returned.
  98. #[inline(always)]
  99. pub fn abs_sub<T: Signed>(x: T, y: T) -> T {
  100. x.abs_sub(&y)
  101. }
  102. /// Returns the sign of the number.
  103. ///
  104. /// For `f32` and `f64`:
  105. ///
  106. /// * `1.0` if the number is positive, `+0.0` or `INFINITY`
  107. /// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
  108. /// * `NaN` if the number is `NaN`
  109. ///
  110. /// For signed integers:
  111. ///
  112. /// * `0` if the number is zero
  113. /// * `1` if the number is positive
  114. /// * `-1` if the number is negative
  115. #[inline(always)] pub fn signum<T: Signed>(value: T) -> T { value.signum() }
  116. /// Raises a value to the power of exp, using exponentiation by squaring.
  117. ///
  118. /// # Example
  119. ///
  120. /// ```rust
  121. /// use num;
  122. ///
  123. /// assert_eq!(num::pow(2i8, 4), 16);
  124. /// assert_eq!(num::pow(6u8, 3), 216);
  125. /// ```
  126. #[inline]
  127. pub fn pow<T: Clone + One + Mul<T, Output = T>>(mut base: T, mut exp: usize) -> T {
  128. if exp == 1 { base }
  129. else {
  130. let mut acc = one::<T>();
  131. while exp > 0 {
  132. if (exp & 1) == 1 {
  133. acc = acc * base.clone();
  134. }
  135. // avoid overflow if we won't need it
  136. if exp > 1 {
  137. base = base.clone() * base;
  138. }
  139. exp = exp >> 1;
  140. }
  141. acc
  142. }
  143. }
  144. #[cfg(test)]
  145. fn hash<T: hash::Hash>(x: &T) -> u64 {
  146. use std::hash::Hasher;
  147. let mut hasher = hash::SipHasher::new();
  148. x.hash(&mut hasher);
  149. hasher.finish()
  150. }