diff --git a/src/bfloat16.jl b/src/bfloat16.jl index 218d48a..59b4e27 100644 --- a/src/bfloat16.jl +++ b/src/bfloat16.jl @@ -45,6 +45,17 @@ end Base.exponent(x::BFloat16) = ((reinterpret(Unsigned, x) & Base.exponent_mask(BFloat16)) >> 7) - Base.exponent_bias(BFloat16) +function Base.decompose(x::BFloat16)::NTuple{3,Int} + isnan(x) && return 0, 0, 0 + isinf(x) && return ifelse(x < 0, -1, 1), 0, 0 + n = reinterpret(UInt16, x) + s = (n & 0x007f) % Int16 + e = ((n & 0x7f80) >> 7) % Int + s |= Int16(e != 0) << 7 + d = ifelse(signbit(x), -1, 1) + s, e - 134 + (e == 0), d +end + function Base.frexp(x::BFloat16) xp = exponent(x) + 1 fr = significand(x) * BFloat16(0.5) diff --git a/test/runtests.jl b/test/runtests.jl index 44f4bcd..6be2afc 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -130,6 +130,15 @@ end @test isnan(prevfloat(BFloat16s.NaNB16)) end +@testset "Decompose BFloat16" begin + for x in randn(100) + bf16 = BFloat16(x) + s,e,d = Base.decompose(bf16) + @test BFloat16(s*2.0^e/d) == bf16 + end +end + + @testset "Next/prevfloat(x,::Integer)" begin x = one(BFloat16) @@ -149,6 +158,5 @@ end @test nextfloat(-floatmin(BFloat16),2^8) > 0 end - include("structure.jl") include("mathfuncs.jl")