use core::fmt::Display;
#[cfg(feature = "std")]
use std::collections::TryReserveError;
#[cfg(not(feature = "std"))]
use alloc::collections::TryReserveError;
#[cfg(not(target_arch = "x86"))]
pub type Word = u64;
#[cfg(not(target_arch = "x86"))]
pub type DoubleWord = u128;
#[cfg(not(target_arch = "x86"))]
pub type SignedWord = i128;
#[cfg(target_arch = "x86")]
pub type Word = u32;
#[cfg(target_arch = "x86")]
pub type DoubleWord = u64;
#[cfg(target_arch = "x86")]
pub type SignedWord = i64;
pub type Exponent = i32;
#[cfg(not(target_arch = "x86"))]
pub const EXPONENT_MAX: Exponent = Exponent::MAX;
#[cfg(target_arch = "x86")]
pub const EXPONENT_MAX: Exponent = Exponent::MAX / 4;
#[cfg(not(target_arch = "x86"))]
pub const EXPONENT_MIN: Exponent = Exponent::MIN;
#[cfg(target_arch = "x86")]
pub const EXPONENT_MIN: Exponent = Exponent::MIN / 4;
pub const WORD_MAX: Word = Word::MAX;
pub const WORD_BASE: DoubleWord = WORD_MAX as DoubleWord + 1;
pub const WORD_BIT_SIZE: usize = core::mem::size_of::<Word>() * 8;
pub const WORD_SIGNIFICANT_BIT: Word = WORD_MAX << (WORD_BIT_SIZE - 1);
pub const DEFAULT_P: usize = 128;
pub const EXPONENT_BIT_SIZE: usize = core::mem::size_of::<Exponent>() * 8;
#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)]
pub enum Sign {
    Neg = -1,
    Pos = 1,
}
impl Sign {
    pub fn invert(&self) -> Self {
        match *self {
            Sign::Pos => Sign::Neg,
            Sign::Neg => Sign::Pos,
        }
    }
    pub fn is_positive(&self) -> bool {
        *self == Sign::Pos
    }
    pub fn is_negative(&self) -> bool {
        *self == Sign::Neg
    }
    pub fn to_int(&self) -> i8 {
        *self as i8
    }
}
#[derive(Debug, Clone, Copy)]
pub enum Error {
    ExponentOverflow(Sign),
    DivisionByZero,
    InvalidArgument,
    MemoryAllocation,
}
#[cfg(feature = "std")]
impl std::error::Error for Error {
    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
        None
    }
}
impl Display for Error {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        let repr = match self {
            Error::ExponentOverflow(s) => {
                if s.is_positive() {
                    "positive overflow"
                } else {
                    "negative overflow"
                }
            }
            Error::DivisionByZero => "division by zero",
            Error::InvalidArgument => "invalid argument",
            Error::MemoryAllocation => "memory allocation failure",
        };
        f.write_str(repr)
    }
}
impl PartialEq for Error {
    fn eq(&self, other: &Self) -> bool {
        match (self, other) {
            (Self::ExponentOverflow(l0), Self::ExponentOverflow(r0)) => l0 == r0,
            _ => core::mem::discriminant(self) == core::mem::discriminant(other),
        }
    }
}
impl From<TryReserveError> for Error {
    fn from(_: TryReserveError) -> Self {
        Error::MemoryAllocation
    }
}
#[derive(PartialEq, Eq, Copy, Clone, Debug)]
pub enum Radix {
    Bin = 2,
    Oct = 8,
    Dec = 10,
    Hex = 16,
}
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
pub enum RoundingMode {
    None = 1,
    Up = 2,
    Down = 4,
    ToZero = 8,
    FromZero = 16,
    ToEven = 32,
    ToOdd = 64,
}