The Microfloat type

Microfloats.MicrofloatType
Microfloat <: AbstractFloat

Abstract supertype for byte-sized floating-point numbers. Concrete subtypes are 8-bit primitive types declared via @microfloat.

Examples

julia> Float8_E4M3 <: Microfloat
true

julia> Float8_E4M3(1.0) + Float8_E4M3(0.5)
Float8_E4M3(1.5)
source

Defining a new Microfloat

Microfloats.@microfloatMacro
@microfloat name [kwargs...]

Declare name as a new 8-bit primitive subtype of Microfloat and register its layout, non-finite encoding, and default overflow policy. The default policy is what overflow_policy returns; callers override per-call with the overflow= keyword on the conversion.

Default policy rule: OVF when the type has any non-finite sentinel (IEEE or NanOnlyAllOnes), else SAT (forced for FiniteOnly since no sentinel encoding exists).

Keyword arguments

  • sign: Number of sign bits: 1 (default) or 0
  • exponent: Number of exponent bits: ≥ 1
  • significand: Number of significand / mantissa bits: ≥ 0
  • nonfinite: IEEE (default), NanOnlyAllOnes, or FiniteOnly.
  • overflow: Default overflow policy instance — typically SAT or OVF. Default: OVF if the type has any non-finite values (IEEE, NanOnlyAllOnes), otherwise SAT (FiniteOnly). Callers can override per call with T(x; overflow=SAT).

Examples

Define a custom 6-bit type with 3 exponent bits, 2 significand bits, and no Inf/NaN encoding:

julia> @microfloat MyFloat6 exponent=3 significand=2 nonfinite=Microfloats.FiniteOnly

julia> MyFloat6(1.5)
MyFloat6(1.5)

julia> Microfloats.bitwidth(MyFloat6)
6

Conversion from larger types rounds to the nearest representable value, breaking ties to even (the value whose bit representation ends in 0):

julia> Float8_E4M3(0.99)
Float8_E4M3(1.0)
source

Public API

Non-Finite Behavior

Microfloats.hasinfFunction
hasinf(::Type{<:Microfloat}) -> Bool

Return true if the type can represent Inf, otherwise false.

Examples

julia> Microfloats.hasinf(Float8_E5M2)
true

julia> Microfloats.hasinf(Float8_E4M3FN)
false
source
Microfloats.hasnanFunction
hasnan(::Type{<:Microfloat}) -> Bool

Return true if the type can represent NaN, otherwise false.

Examples

julia> Microfloats.hasnan(Float8_E4M3FN)
true

julia> Microfloats.hasnan(Float4_E2M1FN)
false
source
Microfloats.non_finite_behaviorFunction
non_finite_behavior(::Type{<:Microfloat}) -> Type{<:NonFiniteBehavior}

Return IEEE, NanOnlyAllOnes, or FiniteOnly based on the trait registered for the concrete type by @microfloat.

Examples

julia> Microfloats.non_finite_behavior(Float8_E5M2)
Microfloats.IEEE

julia> Microfloats.non_finite_behavior(Float8_E4M3FN)
Microfloats.NanOnlyAllOnes

julia> Microfloats.non_finite_behavior(Float4_E2M1FN)
Microfloats.FiniteOnly
source
Microfloats.IEEEType

IEEE-754-style non-finite encoding: an all-ones exponent with significand == 0 encodes ±Inf, and an all-ones exponent with significand ≠ 0 encodes NaN. Compatible with both OVF and SAT.

See also NanOnlyAllOnes, FiniteOnly.

Examples

julia> @microfloat IEEEFloat8 exponent=5 significand=2 nonfinite=Microfloats.IEEE

julia> isinf(IEEEFloat8(Inf)), isnan(IEEEFloat8(NaN))
(true, true)
source
Microfloats.NanOnlyAllOnesType

NaN is the unique all-ones bit pattern across exponent and significand (per sign); no Inf encoding. The slot that would otherwise be Inf is reclaimed for a finite value, extending dynamic range by one step. Compatible with both OVF and SAT; under OVF, overflow maps to NaN.

See also IEEE, FiniteOnly.

Examples

julia> @microfloat FNFloat8 exponent=4 significand=3 nonfinite=Microfloats.NanOnlyAllOnes

julia> Microfloats.hasinf(FNFloat8), Microfloats.hasnan(FNFloat8)
(false, true)
source
Microfloats.FiniteOnlyType

No Inf or NaN — every bit pattern is a finite value, maximizing dynamic range. Requires overflow=SAT, since there is no sentinel encoding to represent overflow.

See also IEEE, NanOnlyAllOnes.

Examples

julia> @microfloat FiniteFloat6 exponent=3 significand=2 nonfinite=Microfloats.FiniteOnly

julia> Microfloats.hasinf(FiniteFloat6), Microfloats.hasnan(FiniteFloat6)
(false, false)
source

Overflow policies

Microfloats.overflow_policyFunction
overflow_policy(::Type{<:Microfloat}) -> OverflowPolicy

Return the overflow policy instance registered by @microfloat — typically OVF or SAT. Sets the default for overflow=... at every conversion call site for this type; override per call with the overflow keyword.

Examples

julia> Microfloats.overflow_policy(Float8_E5M2)
Microfloats.Overflowing()

julia> Microfloats.overflow_policy(Float4_E2M1FN)
Microfloats.Saturating()
source
Microfloats.OVFConstant
OVF

Policy that maps numeric overflow to a sentinel — ±Inf when the format has infinity, otherwise NaN when it has NaN, otherwise a DomainError.

Pass directly as the value of overflow= in @microfloat declarations or as a per-call keyword.

InputIEEENanOnlyAllOnesFiniteOnly
isnan(x)NaNNaNError
abs(x) > floatmax(T)±InfNaNError

The table above describes the default-mode (RoundNearest) behavior. Directed modes like RoundToZero saturate per IEEE-754 regardless of policy.

See also SAT.

Examples

julia> @microfloat OverflowingFloat8 exponent=4 significand=3 overflow=Microfloats.OVF

julia> OverflowingFloat8(10000)
OverflowingFloat8(Inf)

julia> Float8_E4M3(10000; overflow=Microfloats.OVF)
Float8_E4M3(Inf)
source
Microfloats.SATConstant
SAT

Policy that clamps numeric overflow to ±floatmax(T). NaN inputs pass through if T has NaN, else throw a DomainError.

Pass directly as the value of overflow= in @microfloat declarations or as a per-call keyword.

InputIEEENanOnlyAllOnesFiniteOnly
isnan(x)NaNNaNError
abs(x) > floatmax(T)±floatmax±floatmax±floatmax

See also OVF.

Examples

julia> @microfloat SaturatingFloat8 exponent=4 significand=3 overflow=Microfloats.SAT

julia> SaturatingFloat8(10000)
SaturatingFloat8(240.0)

julia> Float8_E4M3(10000; overflow=Microfloats.SAT)
Float8_E4M3(240.0)
source

Reflection

Microfloats.bitwidthFunction
bitwidth(::Type{<:AbstractFloat})

Return the total number of utilized bits — the sum of sign, exponent, and significand bits. For Base float types this matches the storage size; for Microfloat subtypes narrower than 8 bits, the value is smaller than the underlying byte.

Examples

julia> Microfloats.bitwidth(Float4_E2M1FN)
4

julia> Microfloats.bitwidth(Float64)
64
source
Microfloats.sign_bitsFunction
sign_bits(::Type{<:AbstractFloat}) -> Int

Return the number of sign bits (0 for unsigned microfloats, 1 otherwise).

Examples

julia> Microfloats.sign_bits(Float8_E4M3)
1

julia> Microfloats.sign_bits(Float8_E8M0FNU)
0
source
Microfloats.exponent_bitsFunction
exponent_bits(::Type{<:AbstractFloat}) -> Int

Return the number of exponent bits.

Examples

julia> Microfloats.exponent_bits(Float8_E4M3)
4

julia> Microfloats.exponent_bits(Float32)
8
source
Microfloats.significand_bitsFunction
significand_bits(::Type{<:AbstractFloat}) -> Int

Return the number of significand / mantissa bits (excluding the implicit leading 1 of normal IEEE values).

Examples

julia> Microfloats.significand_bits(Float8_E4M3)
3

julia> Microfloats.significand_bits(Float64)
52
source