Cast `Real` to the closest representable value by default (or excess)

I want to get the closest representation by default of a value x of type U<:Real by a value y of type T<:Real.

If T<:Integer, I can do y = floor(T, x)
If T is a Float, I can do T(x).

But none of these methods cover both Integer and Float. Is it safe to assume that if T is not an Integer, I will not get an InexactError? Is there a clean way to do that ?

For context, this question arise du to this issue. I have a function with as input a matrix distmx of type Int64 representing the distance matrix of a graph, and a function f taking as input two vertices s and t and returning a Float. f is assumed to return a heuristic value always greater than the length of the shortest path between s and t.
Generally, the type of the matrix and the type of f will be identical, but it is not to crazy to see this type of scenario: For example, the distances on the graph are known to be integer, but the heuristic is based on the computation of an euclidean distance, giving Float64.
Of course, the user can provide a function returning the truncation of the output of f if he knows that his distance matrix is Integer (He can also cast the matrix to Float, though it is a bit less satisfying in terms of performance), but I think it seems reasonable to assume that he can provide these inputs ?

The problem arise when I store the values of the heuristic in a PriorityQueue. Here, we initialize a PriorityQueue to hold values of the eltype of distmx (so Int64 here), but it returns InexactError when inputting a Float. A first solution would be to answer the question of the post, another would be to allows Float64, but that would be limitating if the input types are both BigFloat, and not satisfying in terms of performance if input types are Int64.

Maybe I can gather the output type of f by taking a random output or using Base.return_types (and assuming f is type stable), but it does not seems really clean…

Can’t you create the PriorityQueue lazily, when you need to actually evaluate the heuristic? Then you can use the actual return value to determine the required type.

It seems reasonable to me to extend floor(T, x) to floating point types where x is higher precision than T.

2 Likes

Yes, this was one of my thoughts, I find it not very clean to get a type by analyzing the output of f, but maybe it is the most reasonable solution.