two-way conversion

This commit is contained in:
numzero 2025-11-02 01:26:06 +03:00
parent 46e1e5c0f9
commit ff731505c0

View File

@ -4,6 +4,11 @@ const E_MAX: u8 = 4;
static_assertions::const_assert_eq!(M_BITS + E_BITS, 8); static_assertions::const_assert_eq!(M_BITS + E_BITS, 8);
pub const EXACT_INT_MAX: u8 = if E_MAX > M_BITS {
2 << M_BITS
} else {
(2 << E_MAX) - 1
};
const M_STORAGE_MAX: u8 = (1 << M_BITS) - 1; const M_STORAGE_MAX: u8 = (1 << M_BITS) - 1;
const E_STORAGE_MAX: u8 = (1 << E_BITS) - 1; const E_STORAGE_MAX: u8 = (1 << E_BITS) - 1;
const M_BIAS: u8 = 1 << M_BITS; const M_BIAS: u8 = 1 << M_BITS;
@ -35,8 +40,17 @@ impl F8 {
} }
impl From<u8> for F8 { impl From<u8> for F8 {
fn from(value: u8) -> Self { fn from(v: u8) -> Self {
todo!() if v == 0 {
return Self(0);
}
let e = v.ilog2() as u8;
let off = e as i8 - M_BITS as i8;
let m = if off >= 0 { v >> off } else { v << -off };
if e > E_MAX {
return Self(0xff);
}
Self::merge(m & M_STORAGE_MAX, e + E_BIAS)
} }
} }
@ -60,5 +74,8 @@ mod tests {
for e in 0..E_MAX { for e in 0..E_MAX {
assert_eq!(u8::from(F8::merge(0, e + E_BIAS)), 1 << e, "e={e}"); assert_eq!(u8::from(F8::merge(0, e + E_BIAS)), 1 << e, "e={e}");
} }
for k in 0..=EXACT_INT_MAX {
assert_eq!(u8::from(F8::from(k)), k);
}
} }
} }