Range behavior for Float32

I ran into the following issue on Julia 1.7.1:

dt = 4.0e-9
l32 = 23_849_999
t = collect(0.0:dt:dt*l32) # Vector{Float64} with 23850000 elements
t0 = collect(LinRange(0.0, dt, l32+1)) # Vector{Float64} with 23850000 elements

dt = Float32(4.0e-9)
t = collect(Float32(0.0):dt:dt*l32) # Vector{Float32} with 23850001 elements
t0 = collect(LinRange(Float32(0.0), dt, l32+1)) # Vector{Float32} with 23850000 elements

Can someone explain why the Float32 vector generated without LinRange has different length?

Float32 is no longer accurate for such large number (not a Julia problem, I’m using 1.8.1, no version will “fix”, just in general an expected problem with IEEE floats, eventually if large enough):

julia> Int64(Float32(23_849_999))

I believe this is one reason for LinRange. So use that or respect:

julia> maxintfloat(Float64)

julia> Int64(maxintfloat(Float32))  # last accurate integer to last digit, much smaller than last (inaccurate) integer

julia> BigInt(floatmax(Float32))  # a bit deceiving