clamp: Turn ifelse into ternary#54038
Conversation
|
The following test case is not covered by only replacing |
|
I see. That might be a bigger issue though: julia> min(typemin(Int), typemin(UInt))
ERROR: InexactError: convert(UInt64, -9223372036854775808)
Stacktrace:
[1] throw_inexacterror(func::Symbol, to::Type, val::Int64)
@ Core ./boot.jl:772
[2] check_sign_bit
@ ./boot.jl:778 [inlined]
[3] toUInt64
@ ./boot.jl:889 [inlined]
[4] UInt64
@ ./boot.jl:919 [inlined]
[5] convert
@ ./number.jl:7 [inlined]
[6] _promote
@ ./promotion.jl:375 [inlined]
[7] promote
@ ./promotion.jl:400 [inlined]
[8] min(x::Int64, y::UInt64)
@ Base ./promotion.jl:494How should we resolve the case when the result is not representable in the promoted type? I understand that |
Maybe it is not needed, if you avoid unnecessary conversions in your approach. Sufficient set of test cases would be good! |
|
Right, this case can be fixed just by reordering the comparisons: function clamp(x::X, lo::L, hi::H) where {X,L,H}
T = promote_type(X, L, H)
v = (x < lo) ? convert(T, lo) : convert(T, x)
return (v > hi) ? convert(T, hi) : v
endLet me know if you can think of other edge-cases. I'll try to come up with some myself. |
|
The potential issue is when With the
Note that if we permit All of the examples listed here also fail in Julia v1.10.2. |
|
The docu of Maybe it is sufficient to just do The promotion to a common type have to be done by explicit conversions. For the other signature that would imply a conversion should do. As a proof of concept and test cases I have: All 3 test cases throw Exception for the current implementations of |
6156be8 to
74aa3ee
Compare
|
Is the method
So you don't see the following methods failing as an issue? clamp(Int64(-1), Int64(-2), UInt64(1))
clamp(Int64(-2), Int64(-1), UInt64(1))
clamp(UInt64(1), Int64(-4), Int64(-3)) |
|
I think, the following cases should work. Please can you add the test cases: The last one indicates IMO a bug in |
Yes. I think this is a consequence of the specs of clamp: " |
Yes, I will!
That's due to Line 123 in 1ae41a2 What if we simply changed that definition to clamp(x, ::Type{T}) where {T<:Integer} = convert(T, clamp(x, typemin(T), typemax(T))) |
That also looks functionally good. |
|
Right, I see. I wanted to avoid duplicating the comparison logic but your argument is strong. |
Fixes JuliaLang#54022 Co-authored-by: Klaus Crusius <KlausC@users.noreply.github.com>
|
LGTM - should be merged |
Fixes #54022