Skip to main content

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_pointer_width = "32"))]
13pub type Word = u64;
14
15/// Doubled word.
16#[cfg(not(target_pointer_width = "32"))]
17pub type DoubleWord = u128;
18
19/// Word with sign.
20#[cfg(not(target_pointer_width = "32"))]
21pub type SignedWord = i128;
22
23/// A word.
24#[cfg(target_pointer_width = "32")]
25pub type Word = u32;
26
27/// Doubled word.
28#[cfg(target_pointer_width = "32")]
29pub type DoubleWord = u64;
30
31/// Word with sign.
32#[cfg(target_pointer_width = "32")]
33pub type SignedWord = i64;
34
35// Word-sized values are used as indices throughout the implementation.
36const _: [(); 1] = [(); (core::mem::size_of::<Word>() <= core::mem::size_of::<usize>()) as usize];
37
38/// An exponent.
39pub type Exponent = i32;
40
41/// Maximum exponent value.
42#[cfg(not(target_pointer_width = "32"))]
43pub const EXPONENT_MAX: Exponent = Exponent::MAX;
44
45/// Maximum exponent value.
46#[cfg(target_pointer_width = "32")]
47pub const EXPONENT_MAX: Exponent = Exponent::MAX / 4;
48
49/// Minimum exponent value.
50#[cfg(not(target_pointer_width = "32"))]
51pub const EXPONENT_MIN: Exponent = Exponent::MIN;
52
53/// Minimum exponent value.
54#[cfg(target_pointer_width = "32")]
55pub const EXPONENT_MIN: Exponent = Exponent::MIN / 4;
56
57/// Maximum value of a word.
58pub const WORD_MAX: Word = Word::MAX;
59
60/// Base of words.
61pub const WORD_BASE: DoubleWord = WORD_MAX as DoubleWord + 1;
62
63/// Size of a word in bits.
64pub const WORD_BIT_SIZE: usize = core::mem::size_of::<Word>() * 8;
65
66/// Word with the most significant bit set.
67pub const WORD_SIGNIFICANT_BIT: Word = WORD_MAX << (WORD_BIT_SIZE - 1);
68
69/// Default precision.
70pub const DEFAULT_P: usize = 128;
71
72/// The size of exponent type in bits.
73pub const EXPONENT_BIT_SIZE: usize = core::mem::size_of::<Exponent>() * 8;
74
75/// Sign.
76#[derive(PartialEq, Eq, Copy, Clone, Debug, Hash)]
77pub enum Sign {
78    /// Negative.
79    Neg = -1,
80
81    /// Positive.
82    Pos = 1,
83}
84
85impl Sign {
86    /// Changes the sign to the opposite.
87    pub fn invert(&self) -> Self {
88        match *self {
89            Sign::Pos => Sign::Neg,
90            Sign::Neg => Sign::Pos,
91        }
92    }
93
94    /// Returns true if `self` is positive.
95    pub fn is_positive(&self) -> bool {
96        *self == Sign::Pos
97    }
98
99    /// Returns true if `self` is negative.
100    pub fn is_negative(&self) -> bool {
101        *self == Sign::Neg
102    }
103
104    /// Returns 1 for the positive sign and -1 for the negative sign.
105    pub fn to_int(&self) -> i8 {
106        *self as i8
107    }
108}
109
110/// Possible errors.
111#[derive(Debug, Clone, Copy)]
112pub enum Error {
113    /// The exponent value becomes greater than the upper limit of the range of exponent values.
114    ExponentOverflow(Sign),
115
116    /// Divizor is zero.
117    DivisionByZero,
118
119    /// Invalid argument.
120    InvalidArgument,
121
122    /// Memory allocation error.
123    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/// Radix.
167#[derive(PartialEq, Eq, Copy, Clone, Debug)]
168pub enum Radix {
169    /// Binary.
170    Bin = 2,
171
172    /// Octal.
173    Oct = 8,
174
175    /// Decimal.
176    Dec = 10,
177
178    /// Hexadecimal.
179    Hex = 16,
180}
181
182/// Rounding modes.
183#[derive(Eq, PartialEq, Debug, Copy, Clone)]
184pub enum RoundingMode {
185    /// Skip rounding operation.
186    None = 1,
187
188    /// Round half toward positive infinity.
189    Up = 2,
190
191    /// Round half toward negative infinity.
192    Down = 4,
193
194    /// Round half toward zero.
195    ToZero = 8,
196
197    /// Round half away from zero.
198    FromZero = 16,
199
200    /// Round half to even.
201    ToEven = 32,
202
203    /// Round half to odd.
204    ToOdd = 64,
205}