#![cfg_attr(docsrs, feature(doc_cfg))]
#![doc(html_root_url = "https://docs.rs/num-bigint/0.4")]
#![warn(rust_2018_idioms)]
#![no_std]
#[macro_use]
extern crate alloc;
#[cfg(feature = "std")]
extern crate std;
use core::fmt;
#[macro_use]
mod macros;
mod bigint;
mod bigrand;
mod biguint;
#[cfg(target_pointer_width = "32")]
type UsizePromotion = u32;
#[cfg(target_pointer_width = "64")]
type UsizePromotion = u64;
#[cfg(target_pointer_width = "32")]
type IsizePromotion = i32;
#[cfg(target_pointer_width = "64")]
type IsizePromotion = i64;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ParseBigIntError {
kind: BigIntErrorKind,
}
#[derive(Debug, Clone, PartialEq, Eq)]
enum BigIntErrorKind {
Empty,
InvalidDigit,
}
impl ParseBigIntError {
fn __description(&self) -> &str {
use crate::BigIntErrorKind::*;
match self.kind {
Empty => "cannot parse integer from empty string",
InvalidDigit => "invalid digit found in string",
}
}
fn empty() -> Self {
ParseBigIntError {
kind: BigIntErrorKind::Empty,
}
}
fn invalid() -> Self {
ParseBigIntError {
kind: BigIntErrorKind::InvalidDigit,
}
}
}
impl fmt::Display for ParseBigIntError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.__description().fmt(f)
}
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl std::error::Error for ParseBigIntError {
fn description(&self) -> &str {
self.__description()
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub struct TryFromBigIntError<T> {
original: T,
}
impl<T> TryFromBigIntError<T> {
fn new(original: T) -> Self {
TryFromBigIntError { original }
}
fn __description(&self) -> &str {
"out of range conversion regarding big integer attempted"
}
pub fn into_original(self) -> T {
self.original
}
}
#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl<T> std::error::Error for TryFromBigIntError<T>
where
T: fmt::Debug,
{
fn description(&self) -> &str {
self.__description()
}
}
impl<T> fmt::Display for TryFromBigIntError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.__description().fmt(f)
}
}
pub use crate::biguint::BigUint;
pub use crate::biguint::ToBigUint;
pub use crate::biguint::U32Digits;
pub use crate::biguint::U64Digits;
pub use crate::bigint::BigInt;
pub use crate::bigint::Sign;
pub use crate::bigint::ToBigInt;
#[cfg(feature = "rand")]
#[cfg_attr(docsrs, doc(cfg(feature = "rand")))]
pub use crate::bigrand::{RandBigInt, RandomBits, UniformBigInt, UniformBigUint};
mod big_digit {
cfg_digit!(
pub(crate) type BigDigit = u32;
pub(crate) type BigDigit = u64;
);
cfg_digit!(
pub(crate) type DoubleBigDigit = u64;
pub(crate) type DoubleBigDigit = u128;
);
pub(crate) const BITS: u8 = BigDigit::BITS as u8;
pub(crate) const HALF_BITS: u8 = BITS / 2;
pub(crate) const HALF: BigDigit = (1 << HALF_BITS) - 1;
pub(crate) const MAX: BigDigit = BigDigit::MAX;
const LO_MASK: DoubleBigDigit = MAX as DoubleBigDigit;
#[inline]
fn get_hi(n: DoubleBigDigit) -> BigDigit {
(n >> BITS) as BigDigit
}
#[inline]
fn get_lo(n: DoubleBigDigit) -> BigDigit {
(n & LO_MASK) as BigDigit
}
#[inline]
pub(crate) fn from_doublebigdigit(n: DoubleBigDigit) -> (BigDigit, BigDigit) {
(get_hi(n), get_lo(n))
}
#[inline]
pub(crate) fn to_doublebigdigit(hi: BigDigit, lo: BigDigit) -> DoubleBigDigit {
DoubleBigDigit::from(lo) | (DoubleBigDigit::from(hi) << BITS)
}
}