astro_float_num/
defs.rs

1//! Definitions.
2
3use core::fmt::Display;
4
5#[cfg(feature = "std")]
6use std::collections::TryReserveError;
7
8#[cfg(not(feature = "std"))]
9use alloc::collections::TryReserveError;
10
11/// A word.
12#[cfg(not(target_arch = "x86"))]
13pub type Word = u64;
14
15/// Doubled word.
16#[cfg(not(target_arch = "x86"))]
17pub type DoubleWord = u128;
18
19/// Word with sign.
20#[cfg(not(target_arch = "x86"))]
21pub type SignedWord = i128;
22
23/// A word.
24#[cfg(target_arch = "x86")]
25pub type Word = u32;
26
27/// Doubled word.
28#[cfg(target_arch = "x86")]
29pub type DoubleWord = u64;
30
31/// Word with sign.
32#[cfg(target_arch = "x86")]
33pub type SignedWord = i64;
34
35/// An exponent.
36pub type Exponent = i32;
37
38/// Maximum exponent value.
39#[cfg(not(target_arch = "x86"))]
40pub const EXPONENT_MAX: Exponent = Exponent::MAX;
41
42/// Maximum exponent value.
43#[cfg(target_arch = "x86")]
44pub const EXPONENT_MAX: Exponent = Exponent::MAX / 4;
45
46/// Minimum exponent value.
47#[cfg(not(target_arch = "x86"))]
48pub const EXPONENT_MIN: Exponent = Exponent::MIN;
49
50/// Minimum exponent value.
51#[cfg(target_arch = "x86")]
52pub const EXPONENT_MIN: Exponent = Exponent::MIN / 4;
53
54/// Maximum value of a word.
55pub const WORD_MAX: Word = Word::MAX;
56
57/// Base of words.
58pub const WORD_BASE: DoubleWord = WORD_MAX as DoubleWord + 1;
59
60/// Size of a word in bits.
61pub const WORD_BIT_SIZE: usize = core::mem::size_of::<Word>() * 8;
62
63/// Word with the most significant bit set.
64pub const WORD_SIGNIFICANT_BIT: Word = WORD_MAX << (WORD_BIT_SIZE - 1);
65
66/// Default precision.
67pub const DEFAULT_P: usize = 128;
68
69/// The size of exponent type in bits.
70pub const EXPONENT_BIT_SIZE: usize = core::mem::size_of::<Exponent>() * 8;
71
72/// Sign.
73#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)]
74pub enum Sign {
75    /// Negative.
76    Neg = -1,
77
78    /// Positive.
79    Pos = 1,
80}
81
82impl Sign {
83    /// Changes the sign to the opposite.
84    pub fn invert(&self) -> Self {
85        match *self {
86            Sign::Pos => Sign::Neg,
87            Sign::Neg => Sign::Pos,
88        }
89    }
90
91    /// Returns true if `self` is positive.
92    pub fn is_positive(&self) -> bool {
93        *self == Sign::Pos
94    }
95
96    /// Returns true if `self` is negative.
97    pub fn is_negative(&self) -> bool {
98        *self == Sign::Neg
99    }
100
101    /// Returns 1 for the positive sign and -1 for the negative sign.
102    pub fn to_int(&self) -> i8 {
103        *self as i8
104    }
105}
106
107/// Possible errors.
108#[derive(Debug, Clone, Copy)]
109pub enum Error {
110    /// The exponent value becomes greater than the upper limit of the range of exponent values.
111    ExponentOverflow(Sign),
112
113    /// Divizor is zero.
114    DivisionByZero,
115
116    /// Invalid argument.
117    InvalidArgument,
118
119    /// Memory allocation error.
120    MemoryAllocation,
121}
122
123#[cfg(feature = "std")]
124impl std::error::Error for Error {
125    fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
126        None
127    }
128}
129
130impl Display for Error {
131    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
132        let repr = match self {
133            Error::ExponentOverflow(s) => {
134                if s.is_positive() {
135                    "positive overflow"
136                } else {
137                    "negative overflow"
138                }
139            }
140            Error::DivisionByZero => "division by zero",
141            Error::InvalidArgument => "invalid argument",
142            Error::MemoryAllocation => "memory allocation failure",
143        };
144        f.write_str(repr)
145    }
146}
147
148impl PartialEq for Error {
149    fn eq(&self, other: &Self) -> bool {
150        match (self, other) {
151            (Self::ExponentOverflow(l0), Self::ExponentOverflow(r0)) => l0 == r0,
152            _ => core::mem::discriminant(self) == core::mem::discriminant(other),
153        }
154    }
155}
156
157impl From<TryReserveError> for Error {
158    fn from(_: TryReserveError) -> Self {
159        Error::MemoryAllocation
160    }
161}
162
163/// Radix.
164#[derive(PartialEq, Eq, Copy, Clone, Debug)]
165pub enum Radix {
166    /// Binary.
167    Bin = 2,
168
169    /// Octal.
170    Oct = 8,
171
172    /// Decimal.
173    Dec = 10,
174
175    /// Hexadecimal.
176    Hex = 16,
177}
178
179/// Rounding modes.
180#[derive(Eq, PartialEq, Debug, Copy, Clone)]
181pub enum RoundingMode {
182    /// Skip rounding operation.
183    None = 1,
184
185    /// Round half toward positive infinity.
186    Up = 2,
187
188    /// Round half toward negative infinity.
189    Down = 4,
190
191    /// Round half toward zero.
192    ToZero = 8,
193
194    /// Round half away from zero.
195    FromZero = 16,
196
197    /// Round half to even.
198    ToEven = 32,
199
200    /// Round half to odd.
201    ToOdd = 64,
202}