use crate::{
binary::{
encode_max,
encode_min,
FixedBinaryBuf,
},
text::ArrayTextBuf,
};
#[derive(Clone, Copy)]
pub struct Bitstring64(FixedBinaryBuf<8, i32>);
impl Bitstring64 {
pub const ZERO: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([0, 0, 0, 0, 0, 0, 56, 34]));
pub const ONE: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([1, 0, 0, 0, 0, 0, 56, 34]));
pub const NEG_ONE: Self =
Bitstring64(FixedBinaryBuf::from_le_bytes([1, 0, 0, 0, 0, 0, 56, 162]));
pub const PI: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
187, 63, 59, 181, 174, 193, 252, 45,
]));
pub const TAU: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
234, 230, 115, 216, 50, 43, 253, 57,
]));
pub const FRAC_PI_2: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
30, 107, 111, 154, 254, 240, 254, 37,
]));
pub const FRAC_PI_3: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
251, 234, 19, 237, 62, 71, 252, 37,
]));
pub const FRAC_PI_4: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
72, 238, 55, 142, 119, 203, 255, 33,
]));
pub const FRAC_PI_6: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
94, 121, 91, 191, 183, 163, 254, 33,
]));
pub const FRAC_PI_8: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
164, 123, 189, 192, 215, 186, 253, 33,
]));
pub const FRAC_1_PI: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
154, 175, 226, 112, 98, 152, 253, 33,
]));
pub const FRAC_2_PI: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
139, 158, 39, 127, 198, 54, 255, 33,
]));
pub const FRAC_2_SQRT_PI: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
146, 110, 113, 78, 126, 168, 252, 37,
]));
pub const SQRT_2: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
91, 204, 39, 238, 68, 20, 254, 37,
]));
pub const FRAC_1_SQRT_2: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
199, 170, 179, 184, 33, 135, 255, 33,
]));
pub const E: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
69, 100, 233, 210, 66, 152, 255, 41,
]));
pub const LOG2_10: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
226, 61, 172, 133, 107, 161, 253, 45,
]));
pub const LOG2_E: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
237, 185, 1, 196, 214, 66, 254, 37,
]));
pub const LOG10_2: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
143, 140, 253, 105, 10, 129, 253, 33,
]));
pub const LOG10_E: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
81, 53, 182, 160, 86, 52, 254, 33,
]));
pub const LN_2: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
205, 102, 171, 200, 49, 59, 255, 33,
]));
pub const LN_10: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
69, 120, 170, 195, 178, 130, 253, 41,
]));
}
impl Bitstring64 {
pub const RADIX: u32 = 10;
pub const DIGITS: u32 = 16;
pub const EPSILON: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([1, 0, 0, 0, 0, 0, 0, 34]));
pub const MIN: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
255, 252, 243, 207, 63, 255, 248, 247,
]));
pub const MIN_POSITIVE: Self =
Bitstring64(FixedBinaryBuf::from_le_bytes([1, 0, 0, 0, 0, 0, 0, 0]));
pub const MAX: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([
255, 252, 243, 207, 63, 255, 248, 119,
]));
pub const MIN_10_EXP: i32 = -398;
pub const MAX_10_EXP: i32 = 369;
pub const NAN: Self = Bitstring64(FixedBinaryBuf::from_le_bytes([0, 0, 0, 0, 0, 0, 0, 124]));
pub const INFINITY: Self =
Bitstring64(FixedBinaryBuf::from_le_bytes([0, 0, 0, 0, 0, 0, 0, 120]));
pub const NEG_INFINITY: Self =
Bitstring64(FixedBinaryBuf::from_le_bytes([0, 0, 0, 0, 0, 0, 0, 248]));
}
impl Bitstring64 {
#[inline]
pub const fn from_le_bytes(bytes: [u8; 8]) -> Self {
Self(FixedBinaryBuf::from_le_bytes(bytes))
}
#[inline]
pub const fn from_be_bytes(bytes: [u8; 8]) -> Self {
Self(FixedBinaryBuf::from_le_bytes([
bytes[7], bytes[6], bytes[5], bytes[4], bytes[3], bytes[2], bytes[1], bytes[0],
]))
}
#[inline]
pub const fn as_le_bytes(&self) -> &[u8; 8] {
self.0.as_le_bytes()
}
#[inline]
pub const fn to_be_bytes(&self) -> [u8; 8] {
let b = self.0.as_le_bytes();
[b[7], b[6], b[5], b[4], b[3], b[2], b[1], b[0]]
}
pub fn zero() -> Self {
Self::from(0u8)
}
pub fn max() -> Self {
let mut buf = FixedBinaryBuf::ZERO;
encode_max(&mut buf, false);
Self(buf)
}
pub fn min() -> Self {
let mut buf = FixedBinaryBuf::ZERO;
encode_max(&mut buf, true);
Self(buf)
}
pub fn min_positive() -> Self {
let mut buf = FixedBinaryBuf::ZERO;
encode_min(&mut buf, false);
Self(buf)
}
}
classify!(Bitstring64);
try_s2d!(ArrayTextBuf::<64> => Bitstring64);
d2s!(Bitstring64);
f2d!(f32 => from_f32 => Bitstring64);
try_f2d!(f64 => from_f64 => Bitstring64);
try_d2f!(Bitstring64 => to_f32 => f32);
try_d2f!(Bitstring64 => to_f64 => f64);
i2d!(i8 => from_i8 => Bitstring64);
i2d!(i16 => from_i16 => Bitstring64);
i2d!(i32 => from_i32 => Bitstring64);
try_i2d!(i64 => from_i64 => Bitstring64);
try_i2d!(i128 => from_i128 => Bitstring64);
try_d2i!(Bitstring64 => to_i8 => i8);
try_d2i!(Bitstring64 => to_i16 => i16);
try_d2i!(Bitstring64 => to_i32 => i32);
try_d2i!(Bitstring64 => to_i64 => i64);
try_d2i!(Bitstring64 => to_i128 => i128);
i2d!(u8 => from_u8 => Bitstring64);
i2d!(u16 => from_u16 => Bitstring64);
i2d!(u32 => from_u32 => Bitstring64);
try_i2d!(u64 => from_u64 => Bitstring64);
try_i2d!(u128 => from_u128 => Bitstring64);
try_d2i!(Bitstring64 => to_u8 => u8);
try_d2i!(Bitstring64 => to_u16 => u16);
try_d2i!(Bitstring64 => to_u32 => u32);
try_d2i!(Bitstring64 => to_u64 => u64);
try_d2i!(Bitstring64 => to_u128 => u128);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn consts_64() {
use core::str::FromStr;
fn is_eq(a: Bitstring64, b: Bitstring64) {
assert_eq!(a.as_le_bytes(), b.as_le_bytes());
}
fn is_eq_f(a: Bitstring64, s: &str) {
assert_eq!(
a.to_string(),
s.chars()
.take((Bitstring64::DIGITS + 1) as usize)
.collect::<String>()
);
}
is_eq(Bitstring64::ZERO, Bitstring64::from_str("0").unwrap());
is_eq(Bitstring64::ONE, Bitstring64::from_str("1").unwrap());
is_eq(Bitstring64::NEG_ONE, Bitstring64::from_str("-1").unwrap());
const PI: &str = "3.14159265358979323846264338327950288";
const TAU: &str = "6.28318530717958647692528676655900577";
const FRAC_PI_2: &str = "1.57079632679489661923132169163975144";
const FRAC_PI_3: &str = "1.04719755119659774615421446109316763";
const FRAC_PI_4: &str = "0.785398163397448309615660845819875721";
const FRAC_PI_6: &str = "0.52359877559829887307710723054658381";
const FRAC_PI_8: &str = "0.39269908169872415480783042290993786";
const FRAC_1_PI: &str = "0.318309886183790671537767526745028724";
const FRAC_2_PI: &str = "0.636619772367581343075535053490057448";
const FRAC_2_SQRT_PI: &str = "1.12837916709551257389615890312154517";
const SQRT_2: &str = "1.41421356237309504880168872420969808";
const FRAC_1_SQRT_2: &str = "0.707106781186547524400844362104849039";
const E: &str = "2.71828182845904523536028747135266250";
const LOG2_10: &str = "3.32192809488736234787031942948939018";
const LOG2_E: &str = "1.44269504088896340735992468100189214";
const LOG10_2: &str = "0.301029995663981195213738894724493027";
const LOG10_E: &str = "0.434294481903251827651128918916605082";
const LN_2: &str = "0.693147180559945309417232121458176568";
const LN_10: &str = "2.30258509299404568401799145468436421";
is_eq_f(Bitstring64::PI, PI);
is_eq_f(Bitstring64::TAU, TAU);
is_eq_f(Bitstring64::FRAC_PI_2, FRAC_PI_2);
is_eq_f(Bitstring64::FRAC_PI_3, FRAC_PI_3);
is_eq_f(Bitstring64::FRAC_PI_4, FRAC_PI_4);
is_eq_f(Bitstring64::FRAC_PI_6, FRAC_PI_6);
is_eq_f(Bitstring64::FRAC_PI_8, FRAC_PI_8);
is_eq_f(Bitstring64::FRAC_1_PI, FRAC_1_PI);
is_eq_f(Bitstring64::FRAC_2_PI, FRAC_2_PI);
is_eq_f(Bitstring64::FRAC_2_SQRT_PI, FRAC_2_SQRT_PI);
is_eq_f(Bitstring64::SQRT_2, SQRT_2);
is_eq_f(Bitstring64::FRAC_1_SQRT_2, FRAC_1_SQRT_2);
is_eq_f(Bitstring64::E, E);
is_eq_f(Bitstring64::LOG2_10, LOG2_10);
is_eq_f(Bitstring64::LOG2_E, LOG2_E);
is_eq_f(Bitstring64::LOG10_2, LOG10_2);
is_eq_f(Bitstring64::LOG10_E, LOG10_E);
is_eq_f(Bitstring64::LN_2, LN_2);
is_eq_f(Bitstring64::LN_10, LN_10);
is_eq(
Bitstring64::EPSILON,
Bitstring64::from_str("0.00000000000001").unwrap(),
);
is_eq(Bitstring64::MIN, Bitstring64::min());
is_eq(Bitstring64::MIN_POSITIVE, Bitstring64::min_positive());
is_eq(Bitstring64::MAX, Bitstring64::max());
is_eq(Bitstring64::NAN, Bitstring64::from_str("nan").unwrap());
is_eq(Bitstring64::INFINITY, Bitstring64::from_str("inf").unwrap());
is_eq(
Bitstring64::NEG_INFINITY,
Bitstring64::from_str("-inf").unwrap(),
);
assert_eq!(
Bitstring64::MIN_10_EXP,
crate::binary::emin::<i32>(64) - (Bitstring64::DIGITS as i32) + 1
);
assert_eq!(
Bitstring64::MAX_10_EXP,
crate::binary::emax::<i32>(64) - (Bitstring64::DIGITS as i32) + 1
);
}
}