Say I have the following 4 arrays
p=Float16[262.0, 289.5, 4.71]
tb=Float16[9.42, -3.555, -7.098]
ts=Float16[357.5, 306.5, 294.8]
nc=UInt16[0xf43a, 0xfff7, 0x312f]
and I then want to compute
floor.(UInt16, (p.-tb)./ts.*nc )
Resulting in
ERROR: InexactError: trunc(UInt16, Inf)
Stacktrace:
[1] trunc
@ .\float.jl:695 [inlined]
[2] floor
@ .\float.jl:294 [inlined]
[3] _broadcast_getindex_evalf
@ .\broadcast.jl:648 [inlined]
[4] _broadcast_getindex
@ .\broadcast.jl:631 [inlined]
[5] getindex
@ .\broadcast.jl:575 [inlined]
[6] macro expansion
@ .\broadcast.jl:984 [inlined]
[7] macro expansion
@ .\simdloop.jl:77 [inlined]
[8] copyto!
@ .\broadcast.jl:983 [inlined]
[9] copyto!
@ .\broadcast.jl:936 [inlined]
[10] copy
@ .\broadcast.jl:908 [inlined]
[11] materialize(bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(floor), Tuple{Base.RefValue{Type{UInt16}}, Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(*), Tuple{Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(/), Tuple{Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(-), Tuple{Vector{Float16}, Vector{Float16}}}, Vector{Float16}}}, Vector{UInt16}}}}})
@ Base.Broadcast .\broadcast.jl:883
[12] top-level scope
@ REPL[238]:1
Which fair enough i probably should have added another parenthesis knowing that the result should always be bounded to lie in the range [0,1] which should be valid
so using instead
floor.(UInt16, ((p.-tb)./ts).*nc )
I get the same error. But if we break it down then we know that
julia> (p.-tb)./ts
3-element Vector{Float16}:
0.7065
0.956
0.04007
and
julia> 0.956*nc[2]
62643.812
so
julia> floor(UInt16,0.956*nc[2])
0xf4b3
Why then will the following not work
floor.(UInt16, ((p.-tb)./ts).*nc )
I assume (based on the stack trace) this has something to do with broadcasting, order of operations, and a fundamental lack of understanding regarding what is going on under the hood when I multiple the Float16 and UInt16 together.
I encountered this as part of a larger timing test in which I was using Distributions.jl to produce random numbers uniformly on the full range of UInt16. I do not actually expect nc to be near type max often (or at all) but now want to understand why I cant multiply the two things together without producing an Inf.
Is there a way to re-arrange the operations or otherwise perform the same math in a type safe manner?