The type of a range step, defined as Float32, changes to Float64

I wonder why in the following example the type of the range step becomes Float64 while originally it was defined as Float32:

julia> x = range(1f0, 10f0, step=0.1f0)

julia> x.step

julia> typeof(x.step)

I guess, as a result of such behavior, sometimes I see failures (related to the type stabiity) when I try to use ranges inside CUDAnative kernels.

Thank you.

1 Like

I don’t know the answer to your question. This will do what you want, though.

function range32(start; stop, step)
    res = range(Float32(start), stop=Float32(stop), step=Float32(step))
    return StepRangeLen{Float32,Float32,Float32}(res)

function range32(start; stop, length)
    res = range(Float32(start), stop=Float32(stop), length=length)
    return StepRangeLen{Float32,Float32,Float32}(res)

I think I encountered something similar before. I believe that range internally uses double the precision in order to compensate loss of precision due to floating point error. Maybe in your case it might make sense to just collect this into an array or it might be better to try and use an integer range and scale it by a float.

1 Like

Thank you for the suggestions and advise.

From the documentation:

    StepRangeLen{T,R,S}(ref::R, step::S, len, [offset=1]) where {T,R,S}
    StepRangeLen(       ref::R, step::S, len, [offset=1]) where {  R,S}

A range `r` where `r[i]` produces values of type `T` (in the second    
form, `T` is deduced automatically), parameterized by a `ref`erence
value, a `step`, and the `len`gth. By default `ref` is the starting
value `r[1]`, but alternatively you can supply it as the value of
`r[offset]` for some other index `1 <= offset <= len`. In conjunction
with `TwicePrecision` this can be used to implement ranges that are
free of roundoff error.

so it seems that, for whatever reason, the way this is implemented, step is in no way guaranteed to be stored as the same type which you gave it is an argument, but the iterable return values are guaranteed to give you a Float32 in your case.

I suspect they did this because of rounding error.