Skip to content

Commit ba9d832

Browse files
authored
Optimize clamp (#194)
1 parent 0446a89 commit ba9d832

File tree

3 files changed

+33
-1
lines changed

3 files changed

+33
-1
lines changed

src/FixedPointNumbers.jl

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import Base: ==, <, <=, -, +, *, /, ~, isapprox,
44
convert, promote_rule, show, bitstring, abs, decompose,
55
isnan, isinf, isfinite, isinteger,
66
zero, oneunit, one, typemin, typemax, floatmin, floatmax, eps, reinterpret,
7-
big, rationalize, float, trunc, round, floor, ceil, bswap,
7+
big, rationalize, float, trunc, round, floor, ceil, bswap, clamp,
88
div, fld, rem, mod, mod1, fld1, min, max, minmax,
99
rand, length
1010

@@ -183,6 +183,12 @@ bitstring(x::FixedPoint) = bitstring(x.i)
183183

184184
bswap(x::X) where {X <: FixedPoint} = sizeof(X) == 1 ? x : X(bswap(x.i), 0)
185185

186+
# At least on Julia v1.5.0 or earlier, the following specialization helps the
187+
# SIMD vectorization. (cf. PR #194)
188+
clamp(x::X, lo::X, hi::X) where {X <: FixedPoint} = X(clamp(x.i, lo.i, hi.i), 0)
189+
190+
clamp(x, ::Type{X}) where {X <: FixedPoint} = clamp(x, typemin(X), typemax(X)) % X
191+
186192
for f in (:zero, :oneunit, :one, :eps, :rawone, :rawtype, :floattype)
187193
@eval begin
188194
$f(x::FixedPoint) = $f(typeof(x))

test/fixed.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,19 @@ end
406406
@test bswap(Q0f15(0.5)) === reinterpret(Q0f15, signed(0x0040))
407407
end
408408

409+
@testset "clamp" begin
410+
@test clamp(0.5Q0f7, -0.8Q0f7, 0.8Q0f7) === 0.5Q0f7
411+
@test clamp(0.5Q0f7, 0.75Q0f7, 0.8Q0f7) === 0.75Q0f7
412+
@test clamp(0.5Q0f7, -0.8Q0f7, 0.25Q0f7) === 0.25Q0f7
413+
@test clamp(0.5, -0.8Q0f7, 0.8Q0f7) === 0.5
414+
@test clamp(0.5f0, 0.75Q0f7, 0.8Q0f7) === 0.75f0
415+
@test clamp(0.5Q0f15, -0.8Q0f7, 0.25Q0f7) === 0.25Q0f15
416+
@test clamp(0.5Q0f7, -Inf, Inf) === 0.5
417+
@test clamp(0.5, Q0f7) === 0.5Q0f7
418+
@test clamp(-1.5f0, Q0f7) === -1.0Q0f7
419+
@test clamp(1.5Q1f6, Q0f7) === 0.992Q0f7
420+
end
421+
409422
@testset "Promotion within Fixed" begin
410423
@test @inferred(promote(Q0f7(0.25), Q0f7(0.75))) ===
411424
(Q0f7(0.25), Q0f7(0.75))

test/normed.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,19 @@ end
338338
@test minmax(N0f8(0.8), N0f8(0.2)) === (N0f8(0.2), N0f8(0.8))
339339
end
340340

341+
@testset "clamp" begin
342+
@test clamp(0.5N0f8, 0.2N0f8, 0.8N0f8) === 0.5N0f8
343+
@test clamp(0.5N0f8, 0.6N0f8, 0.8N0f8) === 0.6N0f8
344+
@test clamp(0.5N0f8, 0.2N0f8, 0.4N0f8) === 0.4N0f8
345+
@test clamp(0.5, 0.2N0f8, 0.8N0f8) === 0.5
346+
@test clamp(0.5f0, 0.6N0f8, 0.8N0f8) === 0.6f0
347+
@test clamp(0.5N0f16, 0.2N0f8, 0.4N0f8) === 0.4N0f16
348+
@test clamp(0.6N0f8, -Inf, Inf) === 0.6
349+
@test clamp(0.5, N0f8) === 0.5N0f8
350+
@test clamp(-1.0f0, N0f8) === 0.0N0f8
351+
@test clamp(2.0N1f7, N0f8) === 1.0N0f8
352+
end
353+
341354
@testset "unit range" begin
342355
@test length(N0f8(0):N0f8(1)) == 2
343356
@test length(N0f8(1):N0f8(0)) == 0

0 commit comments

Comments
 (0)