1#![doc(html_root_url = "https://docs.rs/num-bigint/0.4")]
88#![warn(rust_2018_idioms)]
89#![no_std]
90
91#[cfg(feature = "std")]
92#[macro_use]
93extern crate std;
94
95#[cfg(feature = "std")]
96mod std_alloc {
97 pub(crate) use std::borrow::Cow;
98 #[cfg(any(feature = "quickcheck"))]
99 pub(crate) use std::boxed::Box;
100 pub(crate) use std::string::String;
101 pub(crate) use std::vec::Vec;
102}
103
104#[cfg(not(feature = "std"))]
105#[macro_use]
106extern crate alloc;
107
108#[cfg(not(feature = "std"))]
109mod std_alloc {
110 pub(crate) use alloc::borrow::Cow;
111 #[cfg(any(feature = "quickcheck"))]
112 pub(crate) use alloc::boxed::Box;
113 pub(crate) use alloc::string::String;
114 pub(crate) use alloc::vec::Vec;
115}
116
117use core::fmt;
118#[cfg(feature = "std")]
119use std::error::Error;
120
121#[macro_use]
122mod macros;
123
124mod bigint;
125mod biguint;
126
127#[cfg(feature = "rand")]
128mod bigrand;
129
130#[cfg(target_pointer_width = "32")]
131type UsizePromotion = u32;
132#[cfg(target_pointer_width = "64")]
133type UsizePromotion = u64;
134
135#[cfg(target_pointer_width = "32")]
136type IsizePromotion = i32;
137#[cfg(target_pointer_width = "64")]
138type IsizePromotion = i64;
139
140#[derive(Debug, Clone, PartialEq, Eq)]
141pub struct ParseBigIntError {
142 kind: BigIntErrorKind,
143}
144
145#[derive(Debug, Clone, PartialEq, Eq)]
146enum BigIntErrorKind {
147 Empty,
148 InvalidDigit,
149}
150
151impl ParseBigIntError {
152 fn __description(&self) -> &str {
153 use crate::BigIntErrorKind::*;
154 match self.kind {
155 Empty => "cannot parse integer from empty string",
156 InvalidDigit => "invalid digit found in string",
157 }
158 }
159
160 fn empty() -> Self {
161 ParseBigIntError {
162 kind: BigIntErrorKind::Empty,
163 }
164 }
165
166 fn invalid() -> Self {
167 ParseBigIntError {
168 kind: BigIntErrorKind::InvalidDigit,
169 }
170 }
171}
172
173impl fmt::Display for ParseBigIntError {
174 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
175 self.__description().fmt(f)
176 }
177}
178
179#[cfg(feature = "std")]
180impl Error for ParseBigIntError {
181 fn description(&self) -> &str {
182 self.__description()
183 }
184}
185
186#[cfg(has_try_from)]
188#[derive(Debug, Copy, Clone, PartialEq, Eq)]
189pub struct TryFromBigIntError<T> {
190 original: T,
191}
192
193#[cfg(has_try_from)]
194impl<T> TryFromBigIntError<T> {
195 fn new(original: T) -> Self {
196 TryFromBigIntError { original }
197 }
198
199 fn __description(&self) -> &str {
200 "out of range conversion regarding big integer attempted"
201 }
202
203 pub fn into_original(self) -> T {
209 self.original
210 }
211}
212
213#[cfg(all(feature = "std", has_try_from))]
214impl<T> std::error::Error for TryFromBigIntError<T>
215where
216 T: fmt::Debug,
217{
218 fn description(&self) -> &str {
219 self.__description()
220 }
221}
222
223#[cfg(has_try_from)]
224impl<T> fmt::Display for TryFromBigIntError<T> {
225 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
226 self.__description().fmt(f)
227 }
228}
229
230pub use crate::biguint::BigUint;
231pub use crate::biguint::ToBigUint;
232pub use crate::biguint::U32Digits;
233pub use crate::biguint::U64Digits;
234
235pub use crate::bigint::BigInt;
236pub use crate::bigint::Sign;
237pub use crate::bigint::ToBigInt;
238
239#[cfg(feature = "rand")]
240pub use crate::bigrand::{RandBigInt, RandomBits, UniformBigInt, UniformBigUint};
241
242mod big_digit {
243 #[cfg(not(u64_digit))]
245 pub(crate) type BigDigit = u32;
246 #[cfg(u64_digit)]
247 pub(crate) type BigDigit = u64;
248
249 #[cfg(not(u64_digit))]
252 pub(crate) type DoubleBigDigit = u64;
253 #[cfg(u64_digit)]
254 pub(crate) type DoubleBigDigit = u128;
255
256 #[cfg(not(u64_digit))]
258 pub(crate) type SignedDoubleBigDigit = i64;
259 #[cfg(u64_digit)]
260 pub(crate) type SignedDoubleBigDigit = i128;
261
262 #[cfg(not(u64_digit))]
264 pub(crate) const BITS: u8 = 32;
265 #[cfg(u64_digit)]
266 pub(crate) const BITS: u8 = 64;
267
268 pub(crate) const HALF_BITS: u8 = BITS / 2;
269 pub(crate) const HALF: BigDigit = (1 << HALF_BITS) - 1;
270
271 const LO_MASK: DoubleBigDigit = (1 << BITS) - 1;
272 pub(crate) const MAX: BigDigit = LO_MASK as BigDigit;
273
274 #[inline]
275 fn get_hi(n: DoubleBigDigit) -> BigDigit {
276 (n >> BITS) as BigDigit
277 }
278 #[inline]
279 fn get_lo(n: DoubleBigDigit) -> BigDigit {
280 (n & LO_MASK) as BigDigit
281 }
282
283 #[inline]
285 pub(crate) fn from_doublebigdigit(n: DoubleBigDigit) -> (BigDigit, BigDigit) {
286 (get_hi(n), get_lo(n))
287 }
288
289 #[inline]
291 pub(crate) fn to_doublebigdigit(hi: BigDigit, lo: BigDigit) -> DoubleBigDigit {
292 DoubleBigDigit::from(lo) | (DoubleBigDigit::from(hi) << BITS)
293 }
294}