1#![cfg_attr(not(feature = "std"), no_std)]
2#![allow(clippy::cast_lossless)]
3#![allow(clippy::float_cmp)]
4#![allow(clippy::many_single_char_names)]
5#![allow(clippy::suspicious_arithmetic_impl)]
6#![allow(clippy::verbose_bit_mask)]
7#![allow(clippy::excessive_precision)]
8
9pub mod p8e0;
10pub use self::p8e0::P8E0;
11pub type P8 = P8E0;
12pub mod quire8;
13pub use self::quire8::Q8E0;
14pub type Q8 = Q8E0;
15
16pub mod p16e1;
17pub use self::p16e1::P16E1;
18pub type P16 = P16E1;
19pub mod quire16;
20pub use self::quire16::Q16E1;
21pub type Q16 = Q16E1;
22
23pub mod p32e2;
24pub use self::p32e2::P32E2;
25pub type P32 = P32E2;
26pub mod quire32;
27pub use self::quire32::Q32E2;
28pub type Q32 = Q32E2;
29
30pub mod pxe1;
31pub use pxe1::PxE1;
32
33pub mod pxe2;
34pub use pxe2::PxE2;
35
36mod convert;
37use convert::convert_fraction_p32;
38
39pub(crate) mod macros;
40
41pub mod polynom;
42pub use polynom::Polynom;
43
44macro_rules! with_sign {
45 ($($uint:ty: $ws:ident),*) => {
46 $(
47 const fn $ws(val: $uint, sign: bool) -> $uint {
48 if sign {
49 val.wrapping_neg()
50 } else {
51 val
52 }
53 }
54 )*
55 }
56}
57
58with_sign!(
59 u8: u8_with_sign,
60 u16: u16_with_sign,
61 u32: u32_with_sign,
62 u64: u64_with_sign
63);
64
65const fn lldiv(numer: i64, denom: i64) -> (i64, i64) {
66 let mut quot = numer / denom;
67 let mut rem = numer % denom;
68 if (numer >= 0) && (rem < 0) {
69 quot += 1;
70 rem -= denom;
71 }
72
73 (quot, rem)
74}
75
76const fn div(numer: i32, denom: i32) -> (i32, i32) {
77 let mut quot = numer / denom;
78 let mut rem = numer % denom;
79 if (numer >= 0) && (rem < 0) {
80 quot += 1;
81 rem -= denom;
82 }
83
84 (quot, rem)
85}
86
87const APPROX_RECIP_SQRT0: [u16; 16] = [
88 0xb4c9, 0xffab, 0xaa7d, 0xf11c, 0xa1c5, 0xe4c7, 0x9a43, 0xda29, 0x93b5, 0xd0e5, 0x8ded, 0xc8b7,
89 0x88c6, 0xc16d, 0x8424, 0xbae1,
90];
91const APPROX_RECIP_SQRT1: [u16; 16] = [
92 0xa5a5, 0xea42, 0x8c21, 0xc62d, 0x788f, 0xaa7f, 0x6928, 0x94b6, 0x5cc7, 0x8335, 0x52a6, 0x74e2,
93 0x4a3e, 0x68fe, 0x432b, 0x5efd,
94];
95
96#[derive(Clone, Copy)]
97enum MulAddType {
98 Add,
99 SubC,
100 SubProd,
101}
102
103#[allow(clippy::declare_interior_mutable_const)]
104pub trait MathConsts {
105 const E: Self;
107 const FRAC_1_PI: Self;
109 const FRAC_1_SQRT_2: Self;
111 const FRAC_2_PI: Self;
113 const FRAC_2_SQRT_PI: Self;
115 const FRAC_PI_2: Self;
117 const FRAC_PI_3: Self;
119 const FRAC_PI_4: Self;
121 const FRAC_PI_6: Self;
123 const FRAC_PI_8: Self;
125 const LN_10: Self;
127 const LN_2: Self;
129 const LOG10_E: Self;
131 const LOG2_E: Self;
133 const PI: Self;
135 const SQRT_2: Self;
137 const LOG2_10: Self;
139 const LOG10_2: Self;
141}
142
143#[cfg(test)]
144#[cfg(debug_assertions)]
145const NTESTS32: usize = 1_000_000;
146#[cfg(test)]
147#[cfg(not(debug_assertions))]
148const NTESTS32: usize = 10_000_000;
149#[cfg(test)]
150#[cfg(debug_assertions)]
151const NTESTS16: usize = 100_000;
152#[cfg(test)]
153#[cfg(not(debug_assertions))]
154const NTESTS16: usize = 1000_000;
155#[cfg(test)]
156#[cfg(debug_assertions)]
157const NTESTS8: usize = 1_000;
158#[cfg(test)]
159#[cfg(not(debug_assertions))]
160const NTESTS8: usize = 10_000;
161
162pub trait AssociatedQuire<P> {
163 type Q: Quire<P>;
164}
165
166pub trait Quire<P> {
167 type Bits;
168 fn init() -> Self;
169 fn from_posit(p: P) -> Self;
170 fn to_posit(&self) -> P;
171 fn from_bits(v: Self::Bits) -> Self;
172 fn to_bits(&self) -> Self::Bits;
173 fn is_zero(&self) -> bool;
174 fn is_nar(&self) -> bool;
175 fn add_product(&mut self, p_a: P, p_b: P);
176 fn sub_product(&mut self, p_a: P, p_b: P);
177 fn clear(&mut self);
178 fn neg(&mut self);
179}
180
181#[cfg(feature = "linalg")]
182pub trait QuireDot<T> {
183 type Output;
184 fn quire_dot(&self, rhs: T) -> Self::Output;
185}
186
187#[cfg(feature = "linalg")]
188mod linalg;
189
190trait RawPosit {
191 type UInt;
192 type Int;
193
194 const BITSIZE: u32;
195
196 const EXPONENT_BITS: u32;
197 const EXPONENT_MASK: Self::UInt;
198}
199
200trait RawFloat {
201 type UInt;
202 type Int;
203
204 const BITSIZE: u32;
205
206 const EXPONENT_BITS: u32;
207 const EXPONENT_MASK: Self::UInt;
208
209 const EXPONENT_BIAS: Self::Int;
210
211 const SIGNIFICAND_BITS: Self::UInt;
212 const SIGNIFICAND_MASK: Self::UInt;
213
214 const SIGN_MASK: Self::UInt;
215}
216
217impl RawFloat for f32 {
218 type UInt = u32;
219 type Int = i32;
220
221 const BITSIZE: u32 = 32;
222
223 const EXPONENT_BITS: u32 = 8;
224 const EXPONENT_MASK: Self::UInt = 0x_7f80_0000;
225
226 const EXPONENT_BIAS: Self::Int = (Self::MAX_EXP - 1) as _;
227
228 const SIGNIFICAND_BITS: Self::UInt = (Self::MANTISSA_DIGITS - 1) as _;
229 const SIGNIFICAND_MASK: Self::UInt = 0x_007f_ffff;
230
231 const SIGN_MASK: Self::UInt = 0x8000_0000;
232}
233
234impl RawFloat for f64 {
235 type UInt = u64;
236 type Int = i64;
237
238 const BITSIZE: u32 = 64;
239
240 const EXPONENT_BITS: u32 = 11;
241 const EXPONENT_MASK: Self::UInt = 0x_7ff0_0000_0000_0000;
242
243 const EXPONENT_BIAS: Self::Int = (Self::MAX_EXP - 1) as _;
244
245 const SIGNIFICAND_BITS: Self::UInt = (Self::MANTISSA_DIGITS - 1) as _;
246 const SIGNIFICAND_MASK: Self::UInt = 0x_000f_ffff_ffff_ffff;
247
248 const SIGN_MASK: Self::UInt = 0x_8000_0000_0000_0000;
249}