first steps
This commit is contained in:
commit
1a8542091c
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/target
|
||||||
16
Cargo.lock
generated
Normal file
16
Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
# This file is automatically @generated by Cargo.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
version = 4
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "f8"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"static_assertions",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "static_assertions"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||||
7
Cargo.toml
Normal file
7
Cargo.toml
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
[package]
|
||||||
|
name = "f8"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
static_assertions = "1.1.0"
|
||||||
64
src/lib.rs
Normal file
64
src/lib.rs
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
pub const M_BITS: u8 = 5;
|
||||||
|
pub const E_BITS: u8 = 3;
|
||||||
|
const E_MAX: u8 = 4;
|
||||||
|
|
||||||
|
static_assertions::const_assert_eq!(M_BITS + E_BITS, 8);
|
||||||
|
|
||||||
|
const M_STORAGE_MAX: u8 = (1 << M_BITS) - 1;
|
||||||
|
const E_STORAGE_MAX: u8 = (1 << E_BITS) - 1;
|
||||||
|
const M_BIAS: u8 = 1 << M_BITS;
|
||||||
|
const E_BIAS: u8 = E_STORAGE_MAX - E_MAX;
|
||||||
|
const M_MASK: u8 = M_STORAGE_MAX << E_BITS;
|
||||||
|
const E_MASK: u8 = E_STORAGE_MAX;
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
|
pub struct F8(u8);
|
||||||
|
|
||||||
|
impl F8 {
|
||||||
|
/// Split self into the mantissa and exponent, as stored.
|
||||||
|
fn split(self) -> (u8, u8) {
|
||||||
|
(self.0 >> E_BITS, self.0 & E_MASK)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Split self into integers (m, e) such that `self == m * 2.pow(e)`.
|
||||||
|
fn split_unbias(self) -> (u8, i8) {
|
||||||
|
let (m, e) = self.split();
|
||||||
|
(m | M_BIAS, e as i8 - (E_BIAS + M_BITS) as i8)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn merge(m: u8, e: u8) -> Self {
|
||||||
|
assert!(m <= M_STORAGE_MAX);
|
||||||
|
assert!(e <= E_STORAGE_MAX);
|
||||||
|
Self((m << E_BITS) | e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<u8> for F8 {
|
||||||
|
fn from(value: u8) -> Self {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<F8> for u8 {
|
||||||
|
fn from(value: F8) -> Self {
|
||||||
|
if value.0 == 0 {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
let (m, e) = value.split_unbias();
|
||||||
|
if e >= 0 { m << e } else { m >> -e }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_int_conv() {
|
||||||
|
assert_eq!(u8::from(F8(0)), 0);
|
||||||
|
for e in 0..E_MAX {
|
||||||
|
assert_eq!(u8::from(F8(e + E_BIAS)), 1 << e, "e={e}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user