Skip to main content

Crate f8

Crate f8 

Source
Expand description

A one-byte unsigned normalized number (UNORM8), with no allocation or std.

f8 stores an integer b and represents the real number b / 255. It is not an IEEE floating-point format: there is no exponent, negative zero, infinity, or NaN. All 256 bit patterns are valid and ordered.

§Quantization

Conversion from f32 rounds the exact real product 255 * x to the nearest integer, ties to even, after clamping to [0, 1]. NaN maps to zero. Unlike (x * 255.0).round(), this neither rounds ties away from zero nor introduces an intermediate floating-point rounding at bin boundaries. Conversion to f32 is the correctly rounded value of b / 255.

use f8::f8;

let half = f8::from_f32(0.5);
assert_eq!(half.to_bits(), 128);
assert_eq!(half.to_f32(), 128.0 / 255.0);
assert_eq!(half + half, f8::ONE); // Saturates instead of wrapping.
assert_eq!(half * f8::ONE, half);

§Traits

TraitContract
From<u8>, Into<u8>Lossless raw storage, not a numeric cast.
From<f32>Saturating, nearest-even quantization; NaN becomes zero.
Into<f32>, DisplayNormalized value, not the raw byte.
Eq, Ord, HashCompare/hash the byte; a total numerical order.
Defaultf8::ZERO.
Add, Sub and assignmentsExact UNORM addition/subtraction, saturated.
Mul, Div and assignmentsSaturated, nearest-even UNORM arithmetic.
Sum, ProductLeft folds, starting at zero/one; quantize each step.
Serde (feature serde)A newtype named f8 containing one u8.

Operators and iterator traits accept owned and borrowed values. Division defines 0 / 0 = 0 and positive / 0 = 1; no arithmetic operation panics. Quantized multiplication is not associative. Accumulate in f32 instead when intermediate quantization is undesirable.

§Platforms and Performance

Scalar conversion and arithmetic use integer operations, even on soft-float microcontrollers. f8::from_f32_slice and f8::to_f32_slice reuse caller storage. With simd, x86-64 bulk encoding detects AVX2 and OS support at runtime and uses an integer-only assembly kernel. Other targets, short inputs, and Miri use portable Rust. A compile-time AVX2 target needs no probe. AVX-512 targets stay in Rust so LLVM can use the wider instruction set. Both features (serde, simd) are enabled by default; neither requires std or an allocator. Disable default features for a dependency-free build. Bare-metal x86-64, UEFI, and SGX always use Rust: this crate never probes or assumes ownership of extended SIMD state on those targets. Explicit target features may still let the compiler vectorize the portable loops.

Layout is transparent over u8, with size/alignment one. Slice views are zero-copy and endian-independent. This storage contract corresponds to UNORM8, not any of the E4M3/E5M2 formats sometimes also called “FP8”.

Structs§

f8
A one-byte UNORM representing bits / 255 in the inclusive range [0, 1].