Skip to content

Commit a721658

Browse files
barucdenKlausC
andauthored
clamp: Turn ifelse into ternary (#54038)
Fixes #54022 Co-authored-by: Klaus Crusius <KlausC@users.noreply.github.com>
1 parent 396abe4 commit a721658

File tree

2 files changed

+23
-6
lines changed

2 files changed

+23
-6
lines changed

base/math.jl

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,10 @@ julia> clamp.([11, 8, 5], 10, 6) # an example where lo > hi
9595
10
9696
```
9797
"""
98-
clamp(x::X, lo::L, hi::H) where {X,L,H} =
99-
ifelse(x > hi, convert(promote_type(X,L,H), hi),
100-
ifelse(x < lo,
101-
convert(promote_type(X,L,H), lo),
102-
convert(promote_type(X,L,H), x)))
98+
function clamp(x::X, lo::L, hi::H) where {X,L,H}
99+
T = promote_type(X, L, H)
100+
return (x > hi) ? convert(T, hi) : (x < lo) ? convert(T, lo) : convert(T, x)
101+
end
103102

104103
"""
105104
clamp(x, T)::T
@@ -120,7 +119,14 @@ julia> trunc(Int, 4pi^2)
120119
39
121120
```
122121
"""
123-
clamp(x, ::Type{T}) where {T<:Integer} = clamp(x, typemin(T), typemax(T)) % T
122+
function clamp(x, ::Type{T}) where {T<:Integer}
123+
# delegating to clamp(x, typemin(T), typemax(T)) would promote types
124+
# this way, we avoid unnecessary conversions
125+
# think of, e.g., clamp(big(2) ^ 200, Int16)
126+
lo = typemin(T)
127+
hi = typemax(T)
128+
return (x > hi) ? hi : (x < lo) ? lo : convert(T, x)
129+
end
124130

125131

126132
"""

test/math.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@ has_fma = Dict(
4747
clamp!(x, 1, 3)
4848
@test x == [1.0, 1.0, 2.0, 3.0, 3.0]
4949
end
50+
51+
@test clamp(typemax(UInt64), Int64) === typemax(Int64)
52+
@test clamp(typemin(Int), UInt64) === typemin(UInt64)
53+
@test clamp(Int16(-1), UInt16) === UInt16(0)
54+
@test clamp(-1, 2, UInt(0)) === UInt(2)
55+
@test clamp(typemax(UInt16), Int16) === Int16(32767)
56+
57+
# clamp should not allocate a BigInt for typemax(Int16)
58+
x = big(2) ^ 100
59+
@test (@allocated clamp(x, Int16)) == 0
60+
5061
end
5162

5263
@testset "constants" begin

0 commit comments

Comments
 (0)