use core::ops::Neg;
mod aarch64;
mod sw;
mod x86_64;
#[derive(Debug, Clone, Copy, Default)]
#[allow(non_camel_case_types)]
#[repr(transparent)]
pub struct f16(pub(crate) u16);
impl Neg for f16 {
type Output = Self;
#[inline]
fn neg(self) -> Self::Output {
Self(self.0 ^ (1 << 15))
}
}
impl PartialEq for f16 {
#[inline]
fn eq(&self, other: &Self) -> bool {
let self_exp = (self.0 >> 10) & 0x1F;
let self_mantissa = self.0 & 0x3FF;
let other_exp = (other.0 >> 10) & 0x1F;
let other_mantissa = other.0 & 0x3FF;
let self_is_nan = self_exp == 0x1F && self_mantissa != 0;
let other_is_nan = other_exp == 0x1F && other_mantissa != 0;
if self_is_nan || other_is_nan {
return false;
}
let self_is_zero = (self.0 & 0x7FFF) == 0;
let other_is_zero = (other.0 & 0x7FFF) == 0;
if self_is_zero && other_is_zero {
return true;
}
self.0 == other.0
}
}
impl f16 {
pub const NAN: Self = Self(u16::MAX);
pub const MIN: Self = Self(0xfbff);
pub const MAX: Self = Self(0x7bff);
pub const INFINITY: Self = Self(u16::MAX - 1);
pub const NEG_INFINITY: Self = Self(u16::MAX - 2);
pub const MANTISSA_DIGITS: u32 = 11;
#[inline]
pub const fn is_nan(self) -> bool {
self.0 == Self::NAN.0
}
#[inline]
pub const fn is_infinite(self) -> bool {
self.0 == Self::INFINITY.0 || self.0 == Self::NEG_INFINITY.0
}
#[inline]
pub const fn is_finite(self) -> bool {
!self.is_nan() && !self.is_infinite()
}
#[inline]
pub const fn is_sign_positive(self) -> bool {
(self.0 & (1 << 15)) == 0
}
#[inline]
pub const fn is_sign_negative(self) -> bool {
(self.0 & (1 << 15)) != 0
}
#[inline]
pub const fn from_bits(bits: u16) -> Self {
Self(bits)
}
#[inline]
pub const fn from_be_bytes(bytes: [u8; 2]) -> Self {
Self(u16::from_be_bytes(bytes))
}
#[inline]
pub const fn from_le_bytes(bytes: [u8; 2]) -> Self {
Self(u16::from_le_bytes(bytes))
}
#[inline]
pub const fn from_ne_bytes(bytes: [u8; 2]) -> Self {
Self(u16::from_ne_bytes(bytes))
}
#[inline]
pub const fn to_bits(self) -> u16 {
self.0
}
#[inline]
pub const fn to_be_bytes(self) -> [u8; 2] {
self.0.to_be_bytes()
}
#[inline]
pub const fn to_le_bytes(self) -> [u8; 2] {
self.0.to_le_bytes()
}
#[inline]
pub const fn to_ne_bytes(self) -> [u8; 2] {
self.0.to_ne_bytes()
}
}