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 
11 //! Big Integer Types for Rust
12 //!
13 //! * A [`BigUint`] is unsigned and represented as a vector of digits.
14 //! * A [`BigInt`] is signed and is a combination of [`BigUint`] and [`Sign`].
15 //!
16 //! Common numerical operations are overloaded, so we can treat them
17 //! the same way we treat other numbers.
18 //!
19 //! ## Example
20 //!
21 //! ```rust
22 //! # fn main() {
23 //! use num_bigint::BigUint;
24 //! use num_traits::{Zero, One};
25 //!
26 //! // Calculate large fibonacci numbers.
27 //! fn fib(n: usize) -> BigUint {
28 //!     let mut f0: BigUint = Zero::zero();
29 //!     let mut f1: BigUint = One::one();
30 //!     for _ in 0..n {
31 //!         let f2 = f0 + &f1;
32 //!         f0 = f1;
33 //!         f1 = f2;
34 //!     }
35 //!     f0
36 //! }
37 //!
38 //! // This is a very large number.
39 //! println!("fib(1000) = {}", fib(1000));
40 //! # }
41 //! ```
42 //!
43 //! It's easy to generate large random numbers:
44 //!
45 //! ```rust,ignore
46 //! use num_bigint::{ToBigInt, RandBigInt};
47 //!
48 //! let mut rng = rand::thread_rng();
49 //! let a = rng.gen_bigint(1000);
50 //!
51 //! let low = -10000.to_bigint().unwrap();
52 //! let high = 10000.to_bigint().unwrap();
53 //! let b = rng.gen_bigint_range(&low, &high);
54 //!
55 //! // Probably an even larger number.
56 //! println!("{}", a * b);
57 //! ```
58 //!
59 //! See the "Features" section for instructions for enabling random number generation.
60 //!
61 //! ## Features
62 //!
63 //! The `std` crate feature is enabled by default, and is mandatory before Rust
64 //! 1.36 and the stabilized `alloc` crate.  If you depend on `num-bigint` with
65 //! `default-features = false`, you must manually enable the `std` feature yourself
66 //! if your compiler is not new enough.
67 //!
68 //! ### Random Generation
69 //!
70 //! `num-bigint` supports the generation of random big integers when the `rand`
71 //! feature is enabled. To enable it include rand as
72 //!
73 //! ```toml
74 //! rand = "0.8"
75 //! num-bigint = { version = "0.4", features = ["rand"] }
76 //! ```
77 //!
78 //! Note that you must use the version of `rand` that `num-bigint` is compatible
79 //! with: `0.8`.
80 //!
81 //!
82 //! ## Compatibility
83 //!
84 //! The `num-bigint` crate is tested for rustc 1.31 and greater.
85 
86 #![doc(html_root_url = "https://docs.rs/num-bigint/0.4")]
87 #![warn(rust_2018_idioms)]
88 #![no_std]
89 
90 #[cfg(feature = "std")]
91 #[macro_use]
92 extern crate std;
93 
94 #[cfg(feature = "std")]
95 mod std_alloc {
96     pub(crate) use std::borrow::Cow;
97     #[cfg(feature = "quickcheck")]
98     pub(crate) use std::boxed::Box;
99     pub(crate) use std::string::String;
100     pub(crate) use std::vec::Vec;
101 }
102 
103 #[cfg(not(feature = "std"))]
104 #[macro_use]
105 extern crate alloc;
106 
107 #[cfg(not(feature = "std"))]
108 mod std_alloc {
109     pub(crate) use alloc::borrow::Cow;
110     #[cfg(feature = "quickcheck")]
111     pub(crate) use alloc::boxed::Box;
112     pub(crate) use alloc::string::String;
113     pub(crate) use alloc::vec::Vec;
114 }
115 
116 use core::fmt;
117 #[cfg(feature = "std")]
118 use std::error::Error;
119 
120 #[macro_use]
121 mod macros;
122 
123 mod bigint;
124 mod biguint;
125 
126 #[cfg(feature = "rand")]
127 mod bigrand;
128 
129 #[cfg(target_pointer_width = "32")]
130 type UsizePromotion = u32;
131 #[cfg(target_pointer_width = "64")]
132 type UsizePromotion = u64;
133 
134 #[cfg(target_pointer_width = "32")]
135 type IsizePromotion = i32;
136 #[cfg(target_pointer_width = "64")]
137 type IsizePromotion = i64;
138 
139 #[derive(Debug, Clone, PartialEq, Eq)]
140 pub struct ParseBigIntError {
141     kind: BigIntErrorKind,
142 }
143 
144 #[derive(Debug, Clone, PartialEq, Eq)]
145 enum BigIntErrorKind {
146     Empty,
147     InvalidDigit,
148 }
149 
150 impl ParseBigIntError {
__description(&self) -> &str151     fn __description(&self) -> &str {
152         use crate::BigIntErrorKind::*;
153         match self.kind {
154             Empty => "cannot parse integer from empty string",
155             InvalidDigit => "invalid digit found in string",
156         }
157     }
158 
empty() -> Self159     fn empty() -> Self {
160         ParseBigIntError {
161             kind: BigIntErrorKind::Empty,
162         }
163     }
164 
invalid() -> Self165     fn invalid() -> Self {
166         ParseBigIntError {
167             kind: BigIntErrorKind::InvalidDigit,
168         }
169     }
170 }
171 
172 impl fmt::Display for ParseBigIntError {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result173     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
174         self.__description().fmt(f)
175     }
176 }
177 
178 #[cfg(feature = "std")]
179 impl Error for ParseBigIntError {
description(&self) -> &str180     fn description(&self) -> &str {
181         self.__description()
182     }
183 }
184 
185 /// The error type returned when a checked conversion regarding big integer fails.
186 #[cfg(has_try_from)]
187 #[derive(Debug, Copy, Clone, PartialEq, Eq)]
188 pub struct TryFromBigIntError<T> {
189     original: T,
190 }
191 
192 #[cfg(has_try_from)]
193 impl<T> TryFromBigIntError<T> {
new(original: T) -> Self194     fn new(original: T) -> Self {
195         TryFromBigIntError { original }
196     }
197 
__description(&self) -> &str198     fn __description(&self) -> &str {
199         "out of range conversion regarding big integer attempted"
200     }
201 
202     /// Extract the original value, if available. The value will be available
203     /// if the type before conversion was either [`BigInt`] or [`BigUint`].
into_original(self) -> T204     pub fn into_original(self) -> T {
205         self.original
206     }
207 }
208 
209 #[cfg(all(feature = "std", has_try_from))]
210 impl<T> std::error::Error for TryFromBigIntError<T>
211 where
212     T: fmt::Debug,
213 {
description(&self) -> &str214     fn description(&self) -> &str {
215         self.__description()
216     }
217 }
218 
219 #[cfg(has_try_from)]
220 impl<T> fmt::Display for TryFromBigIntError<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result221     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
222         self.__description().fmt(f)
223     }
224 }
225 
226 pub use crate::biguint::BigUint;
227 pub use crate::biguint::ToBigUint;
228 pub use crate::biguint::U32Digits;
229 pub use crate::biguint::U64Digits;
230 
231 pub use crate::bigint::BigInt;
232 pub use crate::bigint::Sign;
233 pub use crate::bigint::ToBigInt;
234 
235 #[cfg(feature = "rand")]
236 pub use crate::bigrand::{RandBigInt, RandomBits, UniformBigInt, UniformBigUint};
237 
238 mod big_digit {
239     /// A [`BigDigit`] is a [`BigUint`]'s composing element.
240     #[cfg(not(u64_digit))]
241     pub(crate) type BigDigit = u32;
242     #[cfg(u64_digit)]
243     pub(crate) type BigDigit = u64;
244 
245     /// A [`DoubleBigDigit`] is the internal type used to do the computations.  Its
246     /// size is the double of the size of [`BigDigit`].
247     #[cfg(not(u64_digit))]
248     pub(crate) type DoubleBigDigit = u64;
249     #[cfg(u64_digit)]
250     pub(crate) type DoubleBigDigit = u128;
251 
252     /// A [`SignedDoubleBigDigit`] is the signed version of [`DoubleBigDigit`].
253     #[cfg(not(u64_digit))]
254     pub(crate) type SignedDoubleBigDigit = i64;
255     #[cfg(u64_digit)]
256     pub(crate) type SignedDoubleBigDigit = i128;
257 
258     // [`DoubleBigDigit`] size dependent
259     #[cfg(not(u64_digit))]
260     pub(crate) const BITS: u8 = 32;
261     #[cfg(u64_digit)]
262     pub(crate) const BITS: u8 = 64;
263 
264     pub(crate) const HALF_BITS: u8 = BITS / 2;
265     pub(crate) const HALF: BigDigit = (1 << HALF_BITS) - 1;
266 
267     const LO_MASK: DoubleBigDigit = (1 << BITS) - 1;
268     pub(crate) const MAX: BigDigit = LO_MASK as BigDigit;
269 
270     #[inline]
get_hi(n: DoubleBigDigit) -> BigDigit271     fn get_hi(n: DoubleBigDigit) -> BigDigit {
272         (n >> BITS) as BigDigit
273     }
274     #[inline]
get_lo(n: DoubleBigDigit) -> BigDigit275     fn get_lo(n: DoubleBigDigit) -> BigDigit {
276         (n & LO_MASK) as BigDigit
277     }
278 
279     /// Split one [`DoubleBigDigit`] into two [`BigDigit`]s.
280     #[inline]
from_doublebigdigit(n: DoubleBigDigit) -> (BigDigit, BigDigit)281     pub(crate) fn from_doublebigdigit(n: DoubleBigDigit) -> (BigDigit, BigDigit) {
282         (get_hi(n), get_lo(n))
283     }
284 
285     /// Join two [`BigDigit`]s into one [`DoubleBigDigit`].
286     #[inline]
to_doublebigdigit(hi: BigDigit, lo: BigDigit) -> DoubleBigDigit287     pub(crate) fn to_doublebigdigit(hi: BigDigit, lo: BigDigit) -> DoubleBigDigit {
288         DoubleBigDigit::from(lo) | (DoubleBigDigit::from(hi) << BITS)
289     }
290 }
291