lib.rs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. // Copyright 2013-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. //! A Big integer (signed version: `BigInt`, unsigned version: `BigUint`).
  11. //!
  12. //! A `BigUint` is represented as a vector of `BigDigit`s.
  13. //! A `BigInt` is a combination of `BigUint` and `Sign`.
  14. //!
  15. //! Common numerical operations are overloaded, so we can treat them
  16. //! the same way we treat other numbers.
  17. //!
  18. //! ## Example
  19. //!
  20. //! ```rust
  21. //! extern crate num_bigint;
  22. //! extern crate num_traits;
  23. //!
  24. //! # fn main() {
  25. //! use num_bigint::BigUint;
  26. //! use num_traits::{Zero, One};
  27. //! use std::mem::replace;
  28. //!
  29. //! // Calculate large fibonacci numbers.
  30. //! fn fib(n: usize) -> BigUint {
  31. //! let mut f0: BigUint = Zero::zero();
  32. //! let mut f1: BigUint = One::one();
  33. //! for _ in 0..n {
  34. //! let f2 = f0 + &f1;
  35. //! // This is a low cost way of swapping f0 with f1 and f1 with f2.
  36. //! f0 = replace(&mut f1, f2);
  37. //! }
  38. //! f0
  39. //! }
  40. //!
  41. //! // This is a very large number.
  42. //! println!("fib(1000) = {}", fib(1000));
  43. //! # }
  44. //! ```
  45. //!
  46. //! It's easy to generate large random numbers:
  47. //!
  48. //! ```rust
  49. //! extern crate rand;
  50. //! extern crate num_bigint as bigint;
  51. //!
  52. //! # #[cfg(feature = "rand")]
  53. //! # fn main() {
  54. //! use bigint::{ToBigInt, RandBigInt};
  55. //!
  56. //! let mut rng = rand::thread_rng();
  57. //! let a = rng.gen_bigint(1000);
  58. //!
  59. //! let low = -10000.to_bigint().unwrap();
  60. //! let high = 10000.to_bigint().unwrap();
  61. //! let b = rng.gen_bigint_range(&low, &high);
  62. //!
  63. //! // Probably an even larger number.
  64. //! println!("{}", a * b);
  65. //! # }
  66. //!
  67. //! # #[cfg(not(feature = "rand"))]
  68. //! # fn main() {
  69. //! # }
  70. //! ```
  71. #![doc(html_logo_url = "https://rust-num.github.io/num/rust-logo-128x128-blk-v2.png",
  72. html_favicon_url = "https://rust-num.github.io/num/favicon.ico",
  73. html_root_url = "https://rust-num.github.io/num/",
  74. html_playground_url = "http://play.integer32.com/")]
  75. #[cfg(any(feature = "rand", test))]
  76. extern crate rand;
  77. #[cfg(feature = "rustc-serialize")]
  78. extern crate rustc_serialize;
  79. #[cfg(feature = "serde")]
  80. extern crate serde;
  81. extern crate num_integer as integer;
  82. extern crate num_traits as traits;
  83. use std::error::Error;
  84. use std::num::ParseIntError;
  85. use std::fmt;
  86. #[cfg(target_pointer_width = "32")]
  87. type UsizePromotion = u32;
  88. #[cfg(target_pointer_width = "64")]
  89. type UsizePromotion = u64;
  90. #[cfg(target_pointer_width = "32")]
  91. type IsizePromotion = i32;
  92. #[cfg(target_pointer_width = "64")]
  93. type IsizePromotion = i64;
  94. #[derive(Debug, PartialEq)]
  95. pub enum ParseBigIntError {
  96. ParseInt(ParseIntError),
  97. Other,
  98. }
  99. impl fmt::Display for ParseBigIntError {
  100. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  101. match self {
  102. &ParseBigIntError::ParseInt(ref e) => e.fmt(f),
  103. &ParseBigIntError::Other => "failed to parse provided string".fmt(f),
  104. }
  105. }
  106. }
  107. impl Error for ParseBigIntError {
  108. fn description(&self) -> &str {
  109. "failed to parse bigint/biguint"
  110. }
  111. }
  112. impl From<ParseIntError> for ParseBigIntError {
  113. fn from(err: ParseIntError) -> ParseBigIntError {
  114. ParseBigIntError::ParseInt(err)
  115. }
  116. }
  117. #[cfg(test)]
  118. use std::hash;
  119. #[cfg(test)]
  120. fn hash<T: hash::Hash>(x: &T) -> u64 {
  121. use std::hash::{BuildHasher, Hasher};
  122. use std::collections::hash_map::RandomState;
  123. let mut hasher = <RandomState as BuildHasher>::Hasher::new();
  124. x.hash(&mut hasher);
  125. hasher.finish()
  126. }
  127. #[macro_use]
  128. mod macros;
  129. mod biguint;
  130. mod bigint;
  131. pub use biguint::BigUint;
  132. pub use biguint::ToBigUint;
  133. pub use biguint::big_digit;
  134. pub use biguint::big_digit::{BigDigit, DoubleBigDigit, ZERO_BIG_DIGIT};
  135. pub use bigint::Sign;
  136. pub use bigint::BigInt;
  137. pub use bigint::ToBigInt;
  138. pub use bigint::RandBigInt;