#![cfg_attr(not(feature = "std"), no_std)]
#![allow(clippy::cast_lossless)]
#![allow(clippy::float_cmp)]
#![allow(clippy::many_single_char_names)]
#![allow(clippy::suspicious_arithmetic_impl)]
#![allow(clippy::verbose_bit_mask)]
#![allow(clippy::excessive_precision)]
pub mod p8e0;
pub use self::p8e0::P8E0;
pub type P8 = P8E0;
pub mod quire8;
pub use self::quire8::Q8E0;
pub type Q8 = Q8E0;
pub mod p16e1;
pub use self::p16e1::P16E1;
pub type P16 = P16E1;
pub mod quire16;
pub use self::quire16::Q16E1;
pub type Q16 = Q16E1;
pub mod p32e2;
pub use self::p32e2::P32E2;
pub type P32 = P32E2;
pub mod quire32;
pub use self::quire32::Q32E2;
pub type Q32 = Q32E2;
pub mod pxe1;
pub use pxe1::PxE1;
pub mod pxe2;
pub use pxe2::PxE2;
mod convert;
use convert::convert_fraction_p32;
pub(crate) mod macros;
pub mod polynom;
pub use polynom::Polynom;
macro_rules! with_sign {
($($uint:ty: $ws:ident),*) => {
$(
const fn $ws(val: $uint, sign: bool) -> $uint {
if sign {
val.wrapping_neg()
} else {
val
}
}
)*
}
}
with_sign!(
u8: u8_with_sign,
u16: u16_with_sign,
u32: u32_with_sign,
u64: u64_with_sign
);
const fn lldiv(numer: i64, denom: i64) -> (i64, i64) {
let mut quot = numer / denom;
let mut rem = numer % denom;
if (numer >= 0) && (rem < 0) {
quot += 1;
rem -= denom;
}
(quot, rem)
}
const fn div(numer: i32, denom: i32) -> (i32, i32) {
let mut quot = numer / denom;
let mut rem = numer % denom;
if (numer >= 0) && (rem < 0) {
quot += 1;
rem -= denom;
}
(quot, rem)
}
const APPROX_RECIP_SQRT0: [u16; 16] = [
0xb4c9, 0xffab, 0xaa7d, 0xf11c, 0xa1c5, 0xe4c7, 0x9a43, 0xda29, 0x93b5, 0xd0e5, 0x8ded, 0xc8b7,
0x88c6, 0xc16d, 0x8424, 0xbae1,
];
const APPROX_RECIP_SQRT1: [u16; 16] = [
0xa5a5, 0xea42, 0x8c21, 0xc62d, 0x788f, 0xaa7f, 0x6928, 0x94b6, 0x5cc7, 0x8335, 0x52a6, 0x74e2,
0x4a3e, 0x68fe, 0x432b, 0x5efd,
];
#[derive(Clone, Copy)]
enum MulAddType {
Add,
SubC,
SubProd,
}
#[allow(clippy::declare_interior_mutable_const)]
pub trait MathConsts {
const E: Self;
const FRAC_1_PI: Self;
const FRAC_1_SQRT_2: Self;
const FRAC_2_PI: Self;
const FRAC_2_SQRT_PI: Self;
const FRAC_PI_2: Self;
const FRAC_PI_3: Self;
const FRAC_PI_4: Self;
const FRAC_PI_6: Self;
const FRAC_PI_8: Self;
const LN_10: Self;
const LN_2: Self;
const LOG10_E: Self;
const LOG2_E: Self;
const PI: Self;
const SQRT_2: Self;
const LOG2_10: Self;
const LOG10_2: Self;
}
#[cfg(test)]
#[cfg(debug_assertions)]
const NTESTS32: usize = 1_000_000;
#[cfg(test)]
#[cfg(not(debug_assertions))]
const NTESTS32: usize = 10_000_000;
#[cfg(test)]
#[cfg(debug_assertions)]
const NTESTS16: usize = 100_000;
#[cfg(test)]
#[cfg(not(debug_assertions))]
const NTESTS16: usize = 1000_000;
#[cfg(test)]
#[cfg(debug_assertions)]
const NTESTS8: usize = 1_000;
#[cfg(test)]
#[cfg(not(debug_assertions))]
const NTESTS8: usize = 10_000;
pub trait AssociatedQuire<P> {
type Q: Quire<P>;
}
pub trait Quire<P> {
type Bits;
fn init() -> Self;
fn from_posit(p: P) -> Self;
fn to_posit(&self) -> P;
fn from_bits(v: Self::Bits) -> Self;
fn to_bits(&self) -> Self::Bits;
fn is_zero(&self) -> bool;
fn is_nar(&self) -> bool;
fn add_product(&mut self, p_a: P, p_b: P);
fn sub_product(&mut self, p_a: P, p_b: P);
fn clear(&mut self);
fn neg(&mut self);
}
#[cfg(feature = "linalg")]
pub trait QuireDot<T> {
type Output;
fn quire_dot(&self, rhs: T) -> Self::Output;
}
#[cfg(feature = "linalg")]
mod linalg;
trait RawPosit {
type UInt;
type Int;
const BITSIZE: u32;
const EXPONENT_BITS: u32;
const EXPONENT_MASK: Self::UInt;
}
trait RawFloat {
type UInt;
type Int;
const BITSIZE: u32;
const EXPONENT_BITS: u32;
const EXPONENT_MASK: Self::UInt;
const EXPONENT_BIAS: Self::Int;
const SIGNIFICAND_BITS: Self::UInt;
const SIGNIFICAND_MASK: Self::UInt;
const SIGN_MASK: Self::UInt;
}
impl RawFloat for f32 {
type UInt = u32;
type Int = i32;
const BITSIZE: u32 = 32;
const EXPONENT_BITS: u32 = 8;
const EXPONENT_MASK: Self::UInt = 0x_7f80_0000;
const EXPONENT_BIAS: Self::Int = (Self::MAX_EXP - 1) as _;
const SIGNIFICAND_BITS: Self::UInt = (Self::MANTISSA_DIGITS - 1) as _;
const SIGNIFICAND_MASK: Self::UInt = 0x_007f_ffff;
const SIGN_MASK: Self::UInt = 0x8000_0000;
}
impl RawFloat for f64 {
type UInt = u64;
type Int = i64;
const BITSIZE: u32 = 64;
const EXPONENT_BITS: u32 = 11;
const EXPONENT_MASK: Self::UInt = 0x_7ff0_0000_0000_0000;
const EXPONENT_BIAS: Self::Int = (Self::MAX_EXP - 1) as _;
const SIGNIFICAND_BITS: Self::UInt = (Self::MANTISSA_DIGITS - 1) as _;
const SIGNIFICAND_MASK: Self::UInt = 0x_000f_ffff_ffff_ffff;
const SIGN_MASK: Self::UInt = 0x_8000_0000_0000_0000;
}