Truncating Floats into a specific Int size

Hi all.

julia> floor(Int, convert(Float64, typemax(Int)))
ERROR: InexactError: trunc(Int64, 9.223372036854776e18)

I understand why this happens. What I’m looking for here is a nice way of truncating the pathological case of Float64 values around the size of typemax(Int) into an Int.

I’m on a 64 bit machine, so my ints are Int64. I can do something like this:

testfloat = convert(Float64, typemax(Int))
convert(Int, min(floor(Int128, testfloat), typemax(Int)))

but that seems a little mad. Essentially allowing the floor to cast into the Int128 a value that is typemax(Int64)+1, then disallowing that result to be used on the convert call.

I essentially have a float that I wish to clamp between type{min,max}(Int), but can’t see a better solution than invoking the larger Int128 type. Is there a better way to do this? Is there a way to treat the Int32 case better if not?

Maybe:

const maxfloatint = setrounding(BigFloat, RoundDown) do; convert(Float64, BigFloat(typemax(Int))); end
floorclamp(x::Float64) = x > maxfloatint ? typemax(Int) : floor(Int, x)
1 Like

Thanks Steve, certainly looks a lot nicer and passes my tests!