1use core::fmt::Display;
4
5#[cfg(feature = "std")]
6use std::collections::TryReserveError;
7
8#[cfg(not(feature = "std"))]
9use alloc::collections::TryReserveError;
10
11#[cfg(not(target_pointer_width = "32"))]
13pub type Word = u64;
14
15#[cfg(not(target_pointer_width = "32"))]
17pub type DoubleWord = u128;
18
19#[cfg(not(target_pointer_width = "32"))]
21pub type SignedWord = i128;
22
23#[cfg(target_pointer_width = "32")]
25pub type Word = u32;
26
27#[cfg(target_pointer_width = "32")]
29pub type DoubleWord = u64;
30
31#[cfg(target_pointer_width = "32")]
33pub type SignedWord = i64;
34
35const _: [(); 1] = [(); (core::mem::size_of::<Word>() <= core::mem::size_of::<usize>()) as usize];
37
38pub type Exponent = i32;
40
41#[cfg(not(target_pointer_width = "32"))]
43pub const EXPONENT_MAX: Exponent = Exponent::MAX;
44
45#[cfg(target_pointer_width = "32")]
47pub const EXPONENT_MAX: Exponent = Exponent::MAX / 4;
48
49#[cfg(not(target_pointer_width = "32"))]
51pub const EXPONENT_MIN: Exponent = Exponent::MIN;
52
53#[cfg(target_pointer_width = "32")]
55pub const EXPONENT_MIN: Exponent = Exponent::MIN / 4;
56
57pub const WORD_MAX: Word = Word::MAX;
59
60pub const WORD_BASE: DoubleWord = WORD_MAX as DoubleWord + 1;
62
63pub const WORD_BIT_SIZE: usize = core::mem::size_of::<Word>() * 8;
65
66pub const WORD_SIGNIFICANT_BIT: Word = WORD_MAX << (WORD_BIT_SIZE - 1);
68
69pub const DEFAULT_P: usize = 128;
71
72pub const EXPONENT_BIT_SIZE: usize = core::mem::size_of::<Exponent>() * 8;
74
75#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)]
77pub enum Sign {
78 Neg = -1,
80
81 Pos = 1,
83}
84
85impl Sign {
86 pub fn invert(&self) -> Self {
88 match *self {
89 Sign::Pos => Sign::Neg,
90 Sign::Neg => Sign::Pos,
91 }
92 }
93
94 pub fn is_positive(&self) -> bool {
96 *self == Sign::Pos
97 }
98
99 pub fn is_negative(&self) -> bool {
101 *self == Sign::Neg
102 }
103
104 pub fn to_int(&self) -> i8 {
106 *self as i8
107 }
108}
109
110#[derive(Debug, Clone, Copy)]
112pub enum Error {
113 ExponentOverflow(Sign),
115
116 DivisionByZero,
118
119 InvalidArgument,
121
122 MemoryAllocation,
124}
125
126#[cfg(feature = "std")]
127impl std::error::Error for Error {
128 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
129 None
130 }
131}
132
133impl Display for Error {
134 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
135 let repr = match self {
136 Error::ExponentOverflow(s) => {
137 if s.is_positive() {
138 "positive overflow"
139 } else {
140 "negative overflow"
141 }
142 }
143 Error::DivisionByZero => "division by zero",
144 Error::InvalidArgument => "invalid argument",
145 Error::MemoryAllocation => "memory allocation failure",
146 };
147 f.write_str(repr)
148 }
149}
150
151impl PartialEq for Error {
152 fn eq(&self, other: &Self) -> bool {
153 match (self, other) {
154 (Self::ExponentOverflow(l0), Self::ExponentOverflow(r0)) => l0 == r0,
155 _ => core::mem::discriminant(self) == core::mem::discriminant(other),
156 }
157 }
158}
159
160impl From<TryReserveError> for Error {
161 fn from(_: TryReserveError) -> Self {
162 Error::MemoryAllocation
163 }
164}
165
166#[derive(PartialEq, Eq, Copy, Clone, Debug)]
168pub enum Radix {
169 Bin = 2,
171
172 Oct = 8,
174
175 Dec = 10,
177
178 Hex = 16,
180}
181
182#[derive(Eq, PartialEq, Debug, Copy, Clone)]
184pub enum RoundingMode {
185 None = 1,
187
188 Up = 2,
190
191 Down = 4,
193
194 ToZero = 8,
196
197 FromZero = 16,
199
200 ToEven = 32,
202
203 ToOdd = 64,
205}