How to check for a safe cast?

NumPy has numpy.can_cast — NumPy v1.26 Manual. I’d like to know if it exists in a library before I write something simplified based upon sizeof, which I think is what NumPy is mostly doing anyway.

What kind of casting would you like to do? There is convert and reinterpret as the two main kinds I can think of.

julia> hasmethod(convert, Tuple{Type{Int},Int8})

julia> hasmethod(convert, Tuple{Type{Float64},Int8})

julia> hasmethod(convert, Tuple{Type{Float64},Rational})

julia> convert(Int, 0x8)

julia> convert(Float64, 0x8)

julia> convert(Float64, 1//8)
1 Like

I’m trying to reproduce some Python code, so it needs to be stricter than convert. np.can_cast doesn’t let you cast to a type whose size is smaller. For example, here is a very incomplete implementation (missing rules for going from ints to floats, among many other things):

function can_cast(dtype_from::DataType, dtype_to::DataType)
    if dtype_from == dtype_to
        return true
    elseif supertype(dtype_from) == supertype(dtype_to)
        return sizeof(dtype_from) <= sizeof(dtype_to)
    return false
@testset "can_cast" begin
    # safe
    @test can_cast(Int32, Int32)
    @test can_cast(Int32, Int64)
    @test !can_cast(Int64, Int32)

    @test can_cast(Float32, Float32)
    @test can_cast(Float32, Float64)
    @test !can_cast(Float64, Float32)

    @test can_cast(UInt32, UInt32)
    @test can_cast(UInt32, UInt64)
    @test !can_cast(UInt64, UInt32)

I think you may be zooming in too much on this function rather than the problem you are trying to solve. What is the context in which you want to use can_cast? My guess is that you are probably looking for something like promote, but it’s hard to know for sure.

Note that your implementation currently is missing a lot of edge cases, and will be wrong a lot. supertype(dtype_from) == supertype(dtype_to) is not an especially reasonable condition to check becausesupertypes can be nested and adding intermediate supertypes is not a breaking change.