Is there a way to enumerate through all non-NaN values of Float16?


#1

I can make the following list of Float16 values but it generates NaNs as well. I can also get rid of NaN’s. But is there a ready built way to enumerate through all non-NaN values of Float16?

FLOAT16_UNIQS = reinterpret.(Float16, UInt16.(0:2^16-1))

i have trouble understanding the underlying repreaentation of float 16. On wikipedia is says that it only need 15bit in practice so I must be missing something. Clearly exponents of 0 will always be 0 so alot of values are “wasted” but I can seem to find the pattern on which UInt8 gets converted to NaN when reinterpreted as Float16


#2

I’m not an expert, but I think this works

julia> a = realmin(T)
Float16(6.104e-5)

julia> floats = []
0-element Array{Any,1}

julia> while true
       push!(floats,a)
       a = nextfloat(a)
       !isfinite(a) && break
       end

julia> length(floats)
30720

#3

There should be 63490 elements? See below

FLOAT16_UNIQS = reinterpret.(Float16, UInt16.(0:2^16-1))

unique(FLOAT16_UNIQS)

#4

I think you’re missing the negative and subnormal values here, which explains why you get less than half as many results as expected.


#5

This is a bit closer.

julia> floats = [];

julia> a = -Inf16
-Inf16

julia> while true
                     push!(floats,a)
                     a==Inf16 && break
                     a = nextfloat(a)
                     end

julia> length(floats)
63489

julia> setdiff(floats, FLOAT16_UNIQS)
0-element Array{Any,1}

julia> FLOAT16_UNIQS[find(iszero,FLOAT16_UNIQS)]
2-element Array{Float16,1}:
  0.0
 -0.0

So it just missed -0.0 I think.


#6

All the 16 bit NaN values are s11111xx xxxxxxxx, where the 10 bits of xx xxxxxxxx must be non-zero (if all zero, it represents +/- Inf).
Non-NaN values will be in the ranges 0x0000-0x7c00, and 0x8000-0xfc00.